mimalloc icon indicating copy to clipboard operation
mimalloc copied to clipboard

dev3 crashes on Android

Open Noxybot opened this issue 8 months ago • 5 comments

After fixing infinite recursion in https://github.com/microsoft/mimalloc/pull/1057 I was able to launch a build with MI_DEBUG_FULL on Android and it's failing with such callstack:

abort (@abort:44)
_mi_assert_fail (mimalloc/src/options.c:540)
_mi_page_map_register (mimalloc/src/page-map.c:284)
mi_arenas_page_alloc_fresh (mimalloc/src/arena.c:703)
mi_arenas_page_regular_alloc (mimalloc/src/arena.c:727)
_mi_arenas_page_alloc (mimalloc/src/arena.c:766)
mi_page_fresh_alloc (mimalloc/src/page.c:305)
mi_page_fresh (mimalloc/src/page.c:335)
mi_page_queue_find_free_ex (mimalloc/src/page.c:807)
mi_find_free_page (mimalloc/src/page.c:848)
mi_find_page (mimalloc/src/page.c:929)
_mi_malloc_generic (mimalloc/src/page.c:965)
_mi_page_malloc_zero (mimalloc/src/alloc.c:42)
mi_heap_malloc_small_zero (mimalloc/src/alloc.c:151)
_mi_heap_malloc_zero_ex (mimalloc/src/alloc.c:176)
_mi_heap_malloc_zero (mimalloc/src/alloc.c:200)
mi_heap_malloc (mimalloc/src/alloc.c:204)
mi_malloc (mimalloc/src/alloc.c:208)
__register_atfork (@__register_atfork:14)
pthread_once (@pthread_once:37)
scudo_malloc_set_zero_contents (@scudo_malloc_set_zero_contents:55)
__libc_preinit_impl() (@__libc_preinit_impl():16)
__dl__ZL13call_functionPKcPFviPPcS2_ES0_ (@__dl__ZL13call_functionPKcPFviPPcS2_ES0_:38)
__dl__ZL10call_arrayIPFviPPcS1_EEvPKcPT_mbS5_ (@__dl__ZL10call_arrayIPFviPPcS1_EEvPKcPT_mbS5_:46)
__dl__ZN6soinfo17call_constructorsEv (@__dl__ZN6soinfo17call_constructorsEv:96)
__dl__ZN6soinfo17call_constructorsEv (@__dl__ZN6soinfo17call_constructorsEv:40)
__dl__ZN6soinfo17call_constructorsEv (@__dl__ZN6soinfo17call_constructorsEv:40)
__dl__ZN6soinfo17call_constructorsEv (@__dl__ZN6soinfo17call_constructorsEv:40)
__dl__ZL29__linker_init_post_relocationR19KernelArgumentBlockR6soinfo (@__dl__ZL29__linker_init_post_relocationR19KernelArgumentBlockR6soinfo:1048)
__dl___linker_init (@__dl___linker_init:129)
__dl__start (@__dl__start:5)

So the _mi_page_map is NULL in page-map.c:_mi_page_map_register. Any idea what's happening here? Note: it's happening before mi_process_attach was called, but I suspect it's also the case on dev2.

Noxybot avatar Apr 01 '25 00:04 Noxybot

Hi @Noxybot : the fix in #1057 is not quite right -- the root cause is that mi_process_init is not called (which calls _mi_page_map_init which ensures the pagemap is not NULL which causes eventually the assertion to fail). But when I look at the stack trace, I see _mi_malloc_generic is called (because the thread local heap is (presumably) &_mi_heap_empty). If you look at the start of page.c:_mi_malloc_generic it should call mi_heap_get_default which should call _mi_thread_init and then mi_process_init. Somehow that is not happening? Can you break at _mi_malloc_generic and see why the heap is not initialized / why mi_process_init is not called? (I cannot test on Android myself untfortunately :-( )

daanx avatar Apr 01 '25 01:04 daanx

In page.c:_mi_malloc_generic mi_heap_get_default is not happening since this conidtion:

if mi_unlikely(!mi_heap_is_initialized(heap)) {
    heap = mi_heap_get_default(); // calls mi_thread_init
    if mi_unlikely(!mi_heap_is_initialized(heap)) { return NULL; }
  }

is false. In prim.h:mi_prim_get_default_heap we call _mi_heap_main_get -> mi_heap_main_init. So that's the heap we're using later on (heap_main). We don't call neither _mi_thread_init nor mi_process_init in mi_heap_main_init. prim.h:mi_prim_get_default_heap is called when alloc.c:mi_malloc is called for the first time (as you see from the callstack).

Noxybot avatar Apr 01 '25 01:04 Noxybot

Adding mi_thread_init(); to mi_heap_main_init(void) seems to help...

// Initialization of the (statically allocated) main heap, and the main tld and subproc.
static void mi_heap_main_init(void) {
  if (heap_main.cookie == 0) {
    // heap
    heap_main.cookie = 1;
    mi_thread_init(); <--------

Noxybot avatar Apr 01 '25 01:04 Noxybot