diff options
author | Florian Weimer <fweimer@redhat.com> | 2023-10-18 11:30:38 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2023-10-18 11:30:38 +0200 |
commit | dd32e1db386c77c61850a7cbd0c126b7b3c63ece (patch) | |
tree | 9f0c9c3ead1a6be1c63b6841c85ec5597bf10f6a /elf/tst-audit23.c | |
parent | 2ad9b674cf6cd6ba59c064427cb7aeb43a66d8a9 (diff) | |
download | glibc-dd32e1db386c77c61850a7cbd0c126b7b3c63ece.tar.gz glibc-dd32e1db386c77c61850a7cbd0c126b7b3c63ece.tar.xz glibc-dd32e1db386c77c61850a7cbd0c126b7b3c63ece.zip |
Revert "elf: Always call destructors in reverse constructor order (bug 30785)"
This reverts commit 6985865bc3ad5b23147ee73466583dd7fdf65892. Reason for revert: The commit changes the order of ELF destructor calls too much relative to what applications expect or can handle. In particular, during process exit and _dl_fini, after the revert commit, we no longer call the destructors of the main program first; that only happens after some dlopen'ed objects have been destructed. This robs applications of an opportunity to influence destructor order by calling dlclose explicitly from the main program's ELF destructors. A couple of different approaches involving reverse constructor order were tried, and none of them worked really well. It seems we need to keep the dependency sorting in _dl_fini. There is also an ambiguity regarding nested dlopen calls from ELF constructors: Should those destructors run before or after the object that called dlopen? Commit 6985865bc3ad5b2314 used reverse order of the start of ELF constructor calls for destructors, but arguably using completion of constructors is more correct. However, that alone is not sufficient to address application compatibility issues (it does not change _dl_fini ordering at all).
Diffstat (limited to 'elf/tst-audit23.c')
-rw-r--r-- | elf/tst-audit23.c | 44 |
1 files changed, 19 insertions, 25 deletions
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c index 503699c36a..bb7d66c385 100644 --- a/elf/tst-audit23.c +++ b/elf/tst-audit23.c @@ -98,8 +98,6 @@ do_test (int argc, char *argv[]) char *lname; uintptr_t laddr; Lmid_t lmid; - uintptr_t cookie; - uintptr_t namespace; bool closed; } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } }; size_t nobjs = 0; @@ -119,9 +117,6 @@ do_test (int argc, char *argv[]) size_t buffer_length = 0; while (xgetline (&buffer, &buffer_length, out)) { - *strchrnul (buffer, '\n') = '\0'; - printf ("info: subprocess output: %s\n", buffer); - if (startswith (buffer, "la_activity: ")) { uintptr_t cookie; @@ -130,26 +125,29 @@ do_test (int argc, char *argv[]) &cookie); TEST_COMPARE (r, 2); + /* The cookie identifies the object at the head of the link map, + so we only add a new namespace if it changes from the previous + one. This works since dlmopen is the last in the test body. */ + if (cookie != last_act_cookie && last_act_cookie != -1) + TEST_COMPARE (last_act, LA_ACT_CONSISTENT); + if (this_act == LA_ACT_ADD && acts[nacts] != cookie) { - /* The cookie identifies the object at the head of the - link map, so we only add a new namespace if it - changes from the previous one. This works since - dlmopen is the last in the test body. */ - if (cookie != last_act_cookie && last_act_cookie != -1) - TEST_COMPARE (last_act, LA_ACT_CONSISTENT); - acts[nacts++] = cookie; last_act_cookie = cookie; } - /* LA_ACT_DELETE is called multiple times for each - namespace, depending on destruction order. */ + /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD + at program termination (if the tests adds a dlclose or a library + with extra dependencies this will need to be adapted). */ else if (this_act == LA_ACT_DELETE) - last_act_cookie = cookie; + { + last_act_cookie = acts[--nacts]; + TEST_COMPARE (acts[nacts], cookie); + acts[nacts] = 0; + } else if (this_act == LA_ACT_CONSISTENT) { TEST_COMPARE (cookie, last_act_cookie); - last_act_cookie = -1; /* LA_ACT_DELETE must always be followed by an la_objclose. */ if (last_act == LA_ACT_DELETE) @@ -181,8 +179,6 @@ do_test (int argc, char *argv[]) objs[nobjs].lname = lname; objs[nobjs].laddr = laddr; objs[nobjs].lmid = lmid; - objs[nobjs].cookie = cookie; - objs[nobjs].namespace = last_act_cookie; objs[nobjs].closed = false; nobjs++; @@ -205,12 +201,6 @@ do_test (int argc, char *argv[]) if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid) { TEST_COMPARE (objs[i].closed, false); - TEST_COMPARE (objs[i].cookie, cookie); - if (objs[i].namespace == -1) - /* No LA_ACT_ADD before the first la_objopen call. */ - TEST_COMPARE (acts[0], last_act_cookie); - else - TEST_COMPARE (objs[i].namespace, last_act_cookie); objs[i].closed = true; break; } @@ -219,7 +209,11 @@ do_test (int argc, char *argv[]) /* la_objclose should be called after la_activity(LA_ACT_DELETE) for the closed object's namespace. */ TEST_COMPARE (last_act, LA_ACT_DELETE); - seen_first_objclose = true; + if (!seen_first_objclose) + { + TEST_COMPARE (last_act_cookie, cookie); + seen_first_objclose = true; + } } } |