Index | Thread | Search

From:
ASOU Masato <takeasou.masato@gmail.com>
Subject:
Re: ld.so not calling destructor
To:
Mark Kettenis <mark.kettenis@xs4all.nl>
Cc:
tech@openbsd.org
Date:
Wed, 4 Feb 2026 17:13:33 +0900

Download raw body.

Thread
Hi,

On Wed, Feb 4, 2026 at 6:07 AM Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> > From: ASOU Masato <takeasou.masato@gmail.com>
> > 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();