Skip to content

Thread recycling makes Celeste crash #68

@clementgallet

Description

@clementgallet

Crash during Celeste intro. Error message and stack trace of the thread below:

* Assertion at ../../../mono/utils/hazard-pointer.c:149, condition `mono_bitset_test_fast (small_id_table, id)' not met
Thread 4 (Thread 0x7fffb96ce700 (LWP 15511)):
#0  0x00007ffff7b2e24a in __waitpid (pid=15740, stat_loc=0x7fffb96cc9fc, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:30
#1  0x00000000006b4f4e in mono_handle_native_crash ()
#2  <signal handler called>
#3  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#4  0x00007ffff797a2f1 in __GI_abort () at abort.c:79
#5  0x00000000006e0294 in mono_log_write_logfile ()
#6  0x00000000005ff640 in monoeg_g_logv ()
#7  0x00000000005ff796 in monoeg_assertion_message ()
#8  0x00000000005e521a in mono_thread_small_id_free ()
#9  0x00000000005f3ea3 in unregister_thread ()
#10 0x00000000005f5a39 in mono_thread_info_exit ()
#11 0x000000000057e692 in start_wrapper ()
#12 0x00007ffff7d8fa0f in libtas::pthread_start (arg=0x8bd7e50) at /home/clement/libtas-1.3.0/src/libTAS/threadwrappers.cpp:102
#13 0x00007ffff7b23f2a in start_thread (arg=0x7fffb96ce700) at pthread_create.c:463
#14 0x00007ffff7a3aedf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Some threads in Celeste exit by calling pthread_exit. Because we recycle threads, we replace that call by some code (throwing a c++ exception or using setjmp/longjmp are both possible) to return to our wrapper that initially called the game function, so that we can accept a new thread function to execute without actually spawning a new thread.

During the intro of Celeste, a thread exits using pthread_exit, then the game spawns a new thread so this one is recycled. And the crash occurs when this thread is exiting again, before calling pthread_exit, as another thread is already joining this one. I'm unsure what is causing this, maybe mono does not like to have twice the same thread ids. mono_thread_small_id_free may be the relevant function to look into.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions