Index | Thread | Search

From:
ASOU Masato <takeasou.masato@gmail.com>
Subject:
Re: ld.so not calling destructor
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org, Philip Guenther <guenther@openbsd.org>
Date:
Fri, 17 Jan 2025 09:07:56 +0900

Download raw body.

Thread
I applied the patch and ran make in
/usr/src/regress/libexec/ld.so/initfirst/test1/prog1 and it failed
with following:

$ cd /usr/src/regress/libexec/ld.so/initfirst/test1/prog1
$ make
==== do-prog1 ====
./prog1 | cmp -s
/usr/src/regress/libexec/ld.so/initfirst/test1/prog1/expected1 -
*** Error 1 in . (Makefile:22 'do-prog1')
FAILED
*** Error 1 in /usr/src/regress/libexec/ld.so/initfirst/test1/prog1
(<bsd.regress.mk>:105 'regress': if make -C
/usr/src/regress/libexec/ld....)
$ obj/prog1
init if1
init if2
init normal
main
func normal
$ cat expected1
init if1
init if2
init normal
main
func normal
fini normal
fini if1
fini if2
$

The destructor is not called.  Before applying the patch this test
passed.

I'm investigating this issue.
--
ASOU Masato

On Sat, Dec 21, 2024 at 12:37 AM Alexander Bluhm <bluhm@openbsd.org> wrote:
>
> Hi,
>
> The test suite of my new devel/llvm-openmp port fails as ld.so does
> not call the destructor.  OpenMP registers it like this.
>
> __attribute__((destructor)) void __kmp_internal_end_dtor(void) {
>   __kmp_internal_end_atexit();
> }
>
> Debugging in ld.so shows that the library refcount is never decremented
> and so the callback is never invoked.  Diff below fixes the issue.
>
> I this approach correct?
>
> bluhm
>
> Index: libexec/ld.so/library_subr.c
> ===================================================================
> RCS file: /mount/openbsd/cvs/src/libexec/ld.so/library_subr.c,v
> diff -u -p -r1.55 library_subr.c
> --- libexec/ld.so/library_subr.c        27 Apr 2023 12:27:56 -0000      1.55
> +++ libexec/ld.so/library_subr.c        6 Dec 2024 20:28:11 -0000
> @@ -533,6 +533,17 @@ _dl_link_child(elf_object_t *dep, elf_ob
>  }
>
>  void
> +_dl_unlink_children(void)
> +{
> +       elf_object_t *node;
> +
> +       for (node = _dl_objects; node != NULL; node = node->next) {
> +               if (node->refcount > 0)
> +                       _dl_child_refcnt_decrement(node);
> +       }
> +}
> +
> +void
>  object_vec_grow(struct object_vector *vec, int more)
>  {
>         vec->alloc += more;
> Index: libexec/ld.so/loader.c
> ===================================================================
> RCS file: /mount/openbsd/cvs/src/libexec/ld.so/loader.c,v
> 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      6 Dec 2024 20:25:07 -0000
> @@ -202,6 +202,7 @@ _dl_dtors(void)
>
>         /* ORDER? */
>         _dl_unload_dlopen();
> +       _dl_unlink_children();
>
>         DL_DEB(("doing dtors\n"));
>
> Index: libexec/ld.so/resolve.h
> ===================================================================
> RCS file: /mount/openbsd/cvs/src/libexec/ld.so/resolve.h,v
> diff -u -p -r1.108 resolve.h
> --- libexec/ld.so/resolve.h     21 May 2024 05:00:47 -0000      1.108
> +++ libexec/ld.so/resolve.h     6 Dec 2024 20:23:31 -0000
> @@ -318,6 +318,7 @@ int _dl_load_dep_libs(elf_object_t *obje
>  int _dl_rtld(elf_object_t *object);
>  void _dl_call_init(elf_object_t *object);
>  void _dl_link_child(elf_object_t *dep, elf_object_t *p);
> +void _dl_unlink_children(void);
>  void _dl_link_grpsym(elf_object_t *object);
>  void _dl_cache_grpsym_list_setup(elf_object_t *_object);
>  void _dl_link_grpref(elf_object_t *load_group, elf_object_t *load_object);
>