OSDN Git Service

loader: fix leak of child-to-parent links on dlclose()
authorDimitry Ivanov <dimitry@google.com>
Fri, 21 Apr 2017 23:44:48 +0000 (16:44 -0700)
committerDimitry Ivanov <dimitry@google.com>
Sat, 22 Apr 2017 00:59:40 +0000 (17:59 -0700)
Use children instead of parents in is_recursive() - this
allows us to remove code adding links from child to
parent when loading a library.

Bug: 36104177
Test: /data/nativetest/bionic-unit-tests/bionic-unit-tests32 --gtest_filter=dl*
Test: manual - dlopen/dlclose libandroid.so 10 times and see how many blocks are
      used after each dlclose() - make sure they are constant.

Change-Id: I776d47de92101c6ba47f400205ccbfe8844a7cb8

linker/linker.cpp

index 54867dc..d200c22 100644 (file)
@@ -884,12 +884,11 @@ static bool is_recursive(soinfo* si, soinfo* parent) {
   }
 
   if (si == parent) {
-    DL_ERR("recursive link to \"%s\"", si->name);
     return true;
   }
 
-  return !parent->get_parents().visit([&](soinfo* grandparent) {
-    return !is_recursive(si, grandparent);
+  return !si->get_children().visit([&](soinfo* child) {
+    return !is_recursive(child, parent);
   });
 }
 
@@ -928,6 +927,7 @@ static bool find_libraries(const char* const library_names[], size_t library_nam
     soinfo* needed_by = task->get_needed_by();
 
     if (is_recursive(si, needed_by)) {
+      DL_ERR("recursive link to \"%s\"", si->name);
       return false;
     }
 
@@ -1706,7 +1706,6 @@ void soinfo::CallDestructors() {
 
 void soinfo::add_child(soinfo* child) {
   if (has_min_version(0)) {
-    child->parents.push_back(this);
     this->children.push_back(child);
   }
 }