loader: fix d-tor call order
In the case when there are multiple dependencies on
the same library in the local_group the unload may
in some situations (covered now by tests) result
calling d-tors for some libraries prematurely.
In order to have correct call order loader checks if this
is last dependency in local group before adding it to BFS
queue.
Bug: http://b/35201832
Test: bionic-unit-tests --gtest_filter=dl*:Dl*
Test: bionic-unit-tests-glibc --gtest_filter=dl*
Change-Id: I4c6955b9032acc7147a51d9f09b61d9e0818700c
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 3e9e85e..48fb6d1 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1142,8 +1142,9 @@
g_fini_call_order_str += s;
}
-TEST(dlfcn, init_fini_call_order) {
- void* handle = dlopen("libtest_init_fini_order_root.so", RTLD_NOW);
+static void test_init_fini_call_order_for(const char* libname) {
+ g_fini_call_order_str.clear();
+ void* handle = dlopen(libname, RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
typedef int (*get_init_order_number_t)();
get_init_order_number_t get_init_order_number =
@@ -1158,6 +1159,11 @@
ASSERT_EQ("(root)(child)(grandchild)", g_fini_call_order_str);
}
+TEST(dlfcn, init_fini_call_order) {
+ test_init_fini_call_order_for("libtest_init_fini_order_root.so");
+ test_init_fini_call_order_for("libtest_init_fini_order_root2.so");
+}
+
TEST(dlfcn, symbol_versioning_use_v1) {
void* handle = dlopen("libtest_versioned_uselibv1.so", RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();