Skip to content

Commit 8699f19

Browse files
nicopaussclaude
andcommitted
mem-stack: fix TSan race in atfork handler.
ThreadSanitizer reported a data race on _G.all_pools between: - Writer: a worker thread exiting, via thr_detach -> log_shutdown_thread -> mem_stack_pool_wipe -> mem_pool_wipe, which calls dlist_remove on _G.all_pools while holding _G.all_pools_lock. - Reader: the main thread, running the post-fork child handler mem_stack_fix_all_pools_at_fork, which iterated _G.all_pools without acquiring _G.all_pools_lock. Even though the worker thread had finished before fork() was called, there was no happens-before edge between its last dlist_remove and the main thread's atfork-child iteration (no join, and no matching lock acquisition), which TSan correctly flagged. Register prepare/parent handlers that take/release _G.all_pools_lock around fork(). This establishes the happens-before edge through the spinlock, following the standard pthread_atfork pattern. The child handler now unlocks the spinlock after iterating. ``` ================== WARNING: ThreadSanitizer: data race (pid=675506) Read of size 8 at 0x7ffff7b8f9c0 by main thread: #0 mem_stack_fix_all_pools_at_fork src/core/mem-stack.c:801:5 (zchk+0x11847af) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #1 __run_postfork_handlers posix/register-atfork.c:187:9 (libc.so.6+0x10e4aa) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb) #2 ifork src/core/unix.blk:970:11 (zchk+0x11df381) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #3 thr_job_fork ./lib-common/core/thr-job.h:379:17 (zchk+0x5dcbf4) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #4 _z_group_run src/core/z.blk:1043:11 (zchk+0x5d6abe) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #5 _z_group_process src/core/z.blk:1103:16 (zchk+0x5d6825) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #6 z_iop_http2 tests/zchk-iop-http.c:382:1 (zchk+0x932e5d) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #7 z_run src/core/z.blk:1545:9 (zchk+0x5d92c8) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #8 main tests/zchk.c:1206:12 (zchk+0x706599) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) Previous write of size 8 at 0x7ffff7b8f9c0 by thread T23: #0 __dlist_remove ./lib-common/container-dlist.h:160:16 (zchk+0x11860f2) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #1 dlist_remove ./lib-common/container-dlist.h:205:5 (zchk+0x1182926) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #2 mem_pool_wipe src/core/mem-priv.h:67:9 (zchk+0x1183657) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #3 mem_stack_pool_wipe src/core/mem-stack.c:611:5 (zchk+0x1183446) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #4 log_shutdown_thread src/core/log.c:1157:9 (zchk+0x1173c74) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #5 thr_detach src/core/thr.c:50:9 (zchk+0x11db3f5) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #6 thr_hooks_wrapper src/core/thr.c:90:5 (zchk+0x11db90c) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) Location is TLS of main thread. Thread T23 (tid=675323, finished) created by main thread at: #0 pthread_create <null> (zchk+0x40a1ff) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #1 thr_create src/core/thr.c:111:11 (zchk+0x11db717) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #2 thr_fork_threads src/core/thr-job.blk:969:21 (zchk+0x11d6d24) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #3 thr_initialize src/core/thr-job.blk:1140:5 (zchk+0x11d75a5) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #4 module_require_internal src/core/module.c:323:9 (zchk+0x118e8ed) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #5 module_require src/core/module.c:335:5 (zchk+0x118d609) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #6 z_prometheus_client tests/zchk-prometheus.blk:211:5 (zchk+0x9b213e) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #7 z_run src/core/z.blk:1545:9 (zchk+0x5d92c8) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) #8 main tests/zchk.c:1206:12 (zchk+0x706599) (BuildId: fff1872839743e3e2098a0b242dcad9a488e9434) SUMMARY: ThreadSanitizer: data race src/core/mem-stack.c:801:5 in mem_stack_fix_all_pools_at_fork ================== ``` Change-Id: Icb36262c282b990bfe6aca9f4a08bff8ac65b033 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Priv-Id: 22f173e9610d601220f1d3b17de5c417b512d1da
1 parent 7598580 commit 8699f19

1 file changed

Lines changed: 14 additions & 1 deletion

File tree

src/core/mem-stack.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,16 @@ thr_hooks(t_pool_init, t_pool_wipe);
792792

793793
__thread mem_stack_pool_t t_pool_g;
794794

795+
static void mem_stack_all_pools_prepare_fork(void)
796+
{
797+
spin_lock(&_G.all_pools_lock);
798+
}
799+
800+
static void mem_stack_all_pools_parent_fork(void)
801+
{
802+
spin_unlock(&_G.all_pools_lock);
803+
}
804+
795805
static void mem_stack_fix_all_pools_at_fork(void)
796806
{
797807
/* When a process forks, the stack pools of the main thread remain (like
@@ -803,12 +813,15 @@ static void mem_stack_fix_all_pools_at_fork(void)
803813
dlist_remove(&sp->mp.pool_link);
804814
}
805815
}
816+
spin_unlock(&_G.all_pools_lock);
806817
}
807818

808819
__attribute__((constructor))
809820
static void mem_stack_all_pools_init_at_fork(void)
810821
{
811-
pthread_atfork(NULL, NULL, &mem_stack_fix_all_pools_at_fork);
822+
pthread_atfork(&mem_stack_all_pools_prepare_fork,
823+
&mem_stack_all_pools_parent_fork,
824+
&mem_stack_fix_all_pools_at_fork);
812825
}
813826

814827
/* {{{ Module (for print_state method) */

0 commit comments

Comments
 (0)