Fix unload of recursively linked library

  Expanded test for recursive libs. Fixed bug with unnecessary
  soinfo_free of already loaded library.

(cherry picked from commit a6ac54a215d6b64f5cc5a59b66c1dbfbb41ea9f5)

Change-Id: I6907c723d9fbdf6b2777f3f236b1e29b0843edd6
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index ea02c1a..756f2ff 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -207,8 +207,19 @@
 // libtest_with_dependency_loop_a.so
 TEST(dlfcn, dlopen_check_loop) {
   void* handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW);
-  ASSERT_TRUE(handle == NULL);
+  ASSERT_TRUE(handle == nullptr);
   ASSERT_STREQ("dlopen failed: recursive link to \"libtest_with_dependency_loop_a.so\"", dlerror());
+  // This symbol should never be exposed
+  void* f = dlsym(RTLD_DEFAULT, "dlopen_test_invalid_function");
+  ASSERT_TRUE(f == nullptr);
+  ASSERT_SUBSTR("undefined symbol: dlopen_test_invalid_function", dlerror());
+
+  // dlopen second time to make sure that the library wasn't loaded even though dlopen returned null.
+  // This may happen if during cleanup the root library or one of the depended libs were not removed
+  // from soinfo list.
+  handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr);
+  ASSERT_STREQ("dlopen failed: library \"libtest_with_dependency_loop.so\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
 }
 
 TEST(dlfcn, dlopen_failure) {