From: Mark Kettenis Subject: Re: ld.so not calling destructor To: ASOU Masato Cc: tech@openbsd.org, takeasou.masato@gmail.com Date: Tue, 03 Feb 2026 22:07:52 +0100 > From: ASOU Masato > Date: Wed, 21 Jan 2026 10:14:39 +0900 Hi, > The ld.so has a following issue: > > - When a .so file that marked NODELETE is linked, the destructor > defined with __attribute__((destructor)) does not called. This happens because when a NODELETE library gets loaded, we mark all other objects within a group (including the program itself) as NODELETE. And we don't run the destructors for things marked NODELETE. I agree that this is wrong. The diff below fixes that. But unfortunately this breaks another regression test: FAIL libexec/ld.so/initfirst/test2/prog1/prog1 That test fails because now we run the destructor for the program *after* the destructors from shared libraries. And I think that is programatic because the destructors in the program could depend on features in the shared libraries that are removes by the destructors of those shared libraries. My current thinking is that we actually have a bug in how we run the destructors. But that bug is masked because C++ code typically links against libpthread.so which, as you know, is a NODELETE library. But I haven't figured out how to fix that yet. Index: libexec/ld.so/loader.c =================================================================== RCS file: /cvs/src/libexec/ld.so/loader.c,v retrieving revision 1.223 diff -u -p -r1.223 loader.c --- libexec/ld.so/loader.c 22 Jan 2024 02:08:31 -0000 1.223 +++ libexec/ld.so/loader.c 3 Feb 2026 20:52:52 -0000 @@ -206,6 +206,9 @@ _dl_dtors(void) DL_DEB(("doing dtors\n")); _dl_objects->opencount--; + if (_dl_objects->status & STAT_NODELETE) + _dl_objects->opencount--; + _dl_notify_unload_shlib(_dl_objects); _dl_run_all_dtors();