https://bugs.kde.org/show_bug.cgi?id=380269
Bug ID: 380269 Summary: No multithreading in macOS Sierra (10.12) Product: valgrind Version: 3.12 SVN Platform: Mac OS X Disk Images OS: OS X Status: UNCONFIRMED Severity: normal Priority: NOR Component: general Assignee: jsew...@acm.org Reporter: louis.brunner...@gmail.com Target Milestone: --- On macOS Sierra (10.12), if pthread_create is called while using valgrind the program stops because of a SIGSEGV. Snippet of the error: ==22190== Thread 2: ==22190== Invalid read of size 4 ==22190== at 0x10050790D: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib) ==22190== by 0x1005078FA: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib) ==22190== by 0x100507100: thread_start (in /usr/lib/system/libsystem_pthread.dylib) ==22190== Address 0x18 is not stack'd, malloc'd or (recently) free'd After some investigation, this bug comes when starting the new thread just before the routine supplied to pthread_create is called. From my limited understanding of assembly/macOS internals/valgrind, the thread tries to access its thread-local storage (TLS) and fails because gs (the register that seems to be allowed to it on macOS) is 0. This means that valgrind interpret the problematic instruction mov %gs:0x18,%ecx as lea [0+0x18],%ecx While debbuging with gdb and lldb, with and without valgrind, I noted that gs is always 0. So I don't know if it's technically possible but macOS Sierra seems to hide the value of gs from the user, so when the binary is run without valgrind the instruction loads the correct address even though gs is 0. When running with valgrind, gs is taken directly from the register and is always 0 which triggers the bug. The only solution I can see is guessing the address of the TLS and set it as gs' value before going into pthread (in pthread_hijack), e.g. diff --git a/coregrind/m_syswrap/syswrap-amd64-darwin.c b/coregrind/m_syswrap/syswrap-amd64-darwin.c index c827bab..3c926cf 100644 --- a/coregrind/m_syswrap/syswrap-amd64-darwin.c +++ b/coregrind/m_syswrap/syswrap-amd64-darwin.c @@ -364,6 +364,10 @@ void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, vex->guest_R9 = flags; vex->guest_RSP = sp; +#if DARWIN_VERS >= DARWIN_10_12 + vex->guest_GS_CONST = self; +#endif + // Record thread's stack and Mach port and pthread struct tst->os_state.pthread = self; tst->os_state.lwpid = kport; However, I wasn't able to guess a correct value for gs, and with the above fix the program goes on but fails at the next pthread call, example with the above fix applied: ==23490== Thread 2: ==23490== Invalid read of size 4 ==23490== at 0x100508538: _pthread_testcancel (in /usr/lib/system/libsystem_pthread.dylib) ==23490== by 0x1002E0AD4: nanosleep (in /usr/lib/system/libsystem_c.dylib) ==23490== by 0x1002E09D2: sleep (in /usr/lib/system/libsystem_c.dylib) ==23490== by 0x100000E02: slavethread (pth_term_signal.c:27) ==23490== by 0x1005079AE: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib) ==23490== by 0x1005078FA: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib) ==23490== by 0x100507100: thread_start (in /usr/lib/system/libsystem_pthread.dylib) ==23490== Address 0x54485258 is not stack'd, malloc'd or (recently) free'd Note that at this point, gdb shows gs value as 0x4ee4000 instead of 0x700004ee4000, so maybe the value is getting truncated at some point. In previous versions of macOS, valgrind would set guest_GS_CONST in the thread_fast_set_cthread_self (syswrap-darwin.c:9133) trap. However this function is not called before going into the new thread, leaving an invalid value for gs. -- You are receiving this mail because: You are watching all bug changes.