From: ASOU Masato Subject: Re: ld.so not calling destructor To: Alexander Bluhm Cc: tech@openbsd.org, Philip Guenther Date: Fri, 17 Jan 2025 14:19:33 +0900 I applied your patch and following diff: diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c index 43b19855551..53df24cf857 100644 --- a/libexec/ld.so/library_subr.c +++ b/libexec/ld.so/library_subr.c @@ -457,7 +457,8 @@ _dl_child_refcnt_decrement(elf_object_t *object) struct object_vector vec; int i; - object->refcount--; + if (object->refcount > 0) + object->refcount--; if (OBJECT_REF_CNT(object) == 0) for (vec = object->child_vec, i = 0; i < vec.len; i++) _dl_child_refcnt_decrement(vec.vec[i]); @@ -532,6 +533,17 @@ _dl_link_child(elf_object_t *dep, elf_object_t *p) p->load_name)); } As a result, do-prog[1234] were succeeded. However, run-regress-prog1 failed. ==== do-prog1 ==== ./prog1 | cmp -s /usr/src/regress/libexec/ld.so/initfirst/test1/prog1/expected1 - ==== do-prog2 ==== ./prog2 | cmp -s /usr/src/regress/libexec/ld.so/initfirst/test1/prog1/expected2 - ==== do-prog3 ==== ./prog3 | cmp -s /usr/src/regress/libexec/ld.so/initfirst/test1/prog1/expected3 - ==== do-prog4 ==== ./prog4 | cmp -s /usr/src/regress/libexec/ld.so/initfirst/test1/prog1/expected4 - ===> initfirst/test2 ===> initfirst/test2/libae ===> initfirst/test2/libad ===> initfirst/test2/libac ===> initfirst/test2/libab ===> initfirst/test2/libaa ===> initfirst/test2/prog1 ==== run-regress-prog1 ==== [ "`./prog1`" = "DBECAPpacebd" ] *** Error 1 in initfirst/test2/prog1 (Makefile:56 'run-regress-prog1') FAILED The test expects "DBECAPpacebd", but prog1 outputs "DBECAPacebdp" as berow: $ ./initfirst/test2/prog1/obj/prog1 DBECAPacebdp% -- ASOU Masato On Fri, Jan 17, 2025 at 9:07 AM ASOU Masato wrote: > > 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 > (: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 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); > >