-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
I have a tiny program:
#include <jemalloc/jemalloc.h>
#include <chrono>
#include <cstdlib>
#include <string>
#include <thread>
int main(int argc, char* argv[]) {
char* buf[1000];
for (size_t i = 0; i < 1000; ++i) {
buf[i] = (char*)malloc(1024);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
char const* f = "filename.heap";
mallctl("prof.dump", NULL, NULL, &f, sizeof(const char*));
for (size_t i = 0; i < 1000; ++i) {
free((void*)buf[i]);
}
return 0;
}
If I compile this with the following command:
g++ jemalloctest.cpp -o jemalloctest -Wall -O0 -std=c++17 -l jemalloc -static -g
(I used Ubuntu 22.04 and the g++ compiler version 11.2.0-19ubuntu-1).
The resulting executable immediately crashes with this stack trace (provided I set export MALLOC_CONF="prof:true" to activate JEMALLOC heap profiling):
(gdb) bt
#0 0x000000000031453c in pthread_kill ()
#1 0x00000000002ed176 in raise ()
#2 0x00000000002ed520 in abort ()
#3 0x00000000002d3de0 in uw_init_context_1[cold] ()
#4 0x00000000002d3cec in _Unwind_Backtrace ()
#5 0x00000000002ae51e in je_prof_boot2 ()
#6 0x000000000024460b in malloc_init_hard ()
#7 0x000000000024611d in je_malloc_default ()
#8 0x000000000036ebbb in _dl_get_origin ()
#9 0x0000000000377ad7 in _dl_non_dynamic_init ()
#10 0x00000000002d64da in __libc_init_first ()
#11 0x00000000002d80da in __libc_start_main_impl ()
#12 0x000000000023e925 in _start ()
The test program is almost certainly not minimal, since the code in main is not even run, we are in the initialization code before main. I have another, larger example, where we build a whole application using alpine linux and libmusl with static executables. There it does not crash but gets into a deadlock in pretty much the same situation, since malloc_init_hard calls the libunwind initialization routines, which in turn seems to call malloc, which tries again to initialize using malloc_init_hard.