aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengYi Hung <aokblast@FreeBSD.org>2026-03-12 13:40:34 +0000
committerShengYi Hung <aokblast@FreeBSD.org>2026-03-14 04:30:25 +0000
commit9d26b82826d9962d5085bc5d9df7f8a762c57602 (patch)
treeac3dda553dfa740e706305521956730c81d0ee4a
parent728ae49a6b81edb3eec5ab70a63bb83db8f5dce5 (diff)
libc: Fix dtor order in __cxa_thread_atexit
The thread_local variable may creates another thread_local variable inside its dtor. This new object is immediately be registered in __cxa_thread_atexit() and need to be freed before processing another variable. This fixes the libcxx test thread_local_destruction_order.pass.cpp. Reported by: kib Approved by: lwhsu (mentor) MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D55826
-rw-r--r--lib/libc/stdlib/cxa_thread_atexit_impl.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c
index 3123bd12dca8..3d742d90fb44 100644
--- a/lib/libc/stdlib/cxa_thread_atexit_impl.c
+++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c
@@ -119,9 +119,9 @@ walk_cb_nocall(struct cxa_thread_dtor *dtor __unused)
static void
cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *))
{
- struct cxa_thread_dtor *dtor, *tdtor;
+ struct cxa_thread_dtor *dtor;
- LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) {
+ while ((dtor = LIST_FIRST(&dtors)) != NULL) {
LIST_REMOVE(dtor, entry);
cb(dtor);
free(dtor);