author | Rich Felker <dalias@aerifal.cx> | 2024年07月24日 12:33:46 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2024年07月24日 12:33:46 -0400 |
commit | 9ee6f104075fa6c37bb57a4ef406f3ff290b586c (patch) | |
tree | 787fc5423a68c66a6f31c3e9adca570688400b6f /src | |
parent | 8cca79a72cccbdb54726125d690d7d0095fc2409 (diff) | |
download | musl-9ee6f104075fa6c37bb57a4ef406f3ff290b586c.tar.gz |
-rw-r--r-- | src/exit/atexit.c | 12 |
diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 854e9fdd..92c91c9d 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -19,6 +19,7 @@ static struct fl void *a[COUNT]; } builtin, *head; +static int finished_atexit; static int slot; static volatile int lock[1]; volatile int *const __atexit_lockptr = lock; @@ -34,6 +35,10 @@ void __funcs_on_exit() func(arg); LOCK(lock); } + /* Unlock to prevent deadlock if a global dtor + * attempts to call atexit. */ + finished_atexit = 1; + UNLOCK(lock); } void __cxa_finalize(void *dso) @@ -44,6 +49,13 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { LOCK(lock); + /* Prevent dtors from registering further atexit + * handlers that would never be run. */ + if (finished_atexit) { + UNLOCK(lock); + return -1; + } + /* Defer initialization of head so it can be in BSS */ if (!head) head = &builtin; |