From: ASOU Masato Subject: Re: ld.so not calling destructor To: Mark Kettenis Cc: tech@openbsd.org Date: Wed, 4 Feb 2026 17:13:33 +0900 Hi, On Wed, Feb 4, 2026 at 6:07 AM Mark Kettenis wrote: > > > 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: Yes, I think this diff is part of the solution to this problem. > 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. I agree. I think a fundamental change is needed. > But I haven't figured out how to fix that yet. Me too. -- ASOU Masato > > 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();