>>> So, I think we should either fix the check or remove it.
>>
>> After spending too much time debugging symbol resolution conflicts,
>> I'd try my best to have _some_ checking in runtime.
>>
>> One option (proposed by Jakub) would be to check that libasan precedes
>> libc.so, libpthread.so, etc.
>> The code is going to be somewhat ugly though...
> Let's try and see the code?

I had something like this in mind.

-Y

-- 
You received this message because you are subscribed to the Google Groups 
"address-sanitizer" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
Index: test/asan/TestCases/Linux/asan_dlopen_test.cc
===================================================================
--- test/asan/TestCases/Linux/asan_dlopen_test.cc       (revision 209499)
+++ test/asan/TestCases/Linux/asan_dlopen_test.cc       (working copy)
@@ -11,4 +11,4 @@
   return 0;
 }
 
-// CHECK: ASan runtime does not come first in initial library list
+// CHECK: ASan runtime does not precede
Index: lib/asan/asan_linux.cc
===================================================================
--- lib/asan/asan_linux.cc      (revision 209499)
+++ lib/asan/asan_linux.cc      (working copy)
@@ -85,19 +85,43 @@
 void AsanCheckDynamicRTPrereqs() {}
 void AsanCheckIncompatibleRT() {}
 #else
-static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,
-                                void *data) {
-  // Continue until the first dynamic library is found
+static bool IsDynamicRTName(const char *libname) {
+  return internal_strstr(libname, "libclang_rt.asan") ||
+    internal_strstr(libname, "libasan.so");
+}
+
+static int VerifyDSOOrdering(struct dl_phdr_info *info, size_t size,
+                                void *) {
   if (!info->dlpi_name || info->dlpi_name[0] == 0)
     return 0;
 
-  *(const char **)data = info->dlpi_name;
-  return 1;
+  if (IsDynamicRTName(info->dlpi_name))
+    return 1;
+
+  static const char *stdlibs[] = {
+    "/libstdc++.so",
+    "/libpthread.so",
+    "/libdl.so",
+    "/libm.so",
+    "/libc.so",
+    0
+  };
+
+  for (const char **lib = stdlibs; *lib; ++lib) {
+    if (internal_strstr(info->dlpi_name, *lib)) {
+      Report("ASan runtime does not precede %s in initial library list; "
+             "you should either link runtime to your application or "
+             "manually preload it with LD_PRELOAD.\n", *lib);
+      Die();
+    }
+  }
+
+  return 0;
 }
 
-static bool IsDynamicRTName(const char *libname) {
-  return internal_strstr(libname, "libclang_rt.asan") ||
-    internal_strstr(libname, "libasan.so");
+void AsanCheckDynamicRTPrereqs() {
+  // Ensure that dynamic RT precedes libc in list of loaded DSOs
+  dl_iterate_phdr(VerifyDSOOrdering, 0);
 }
 
 static void ReportIncompatibleRT() {
@@ -105,18 +129,6 @@
   Die();
 }
 
-void AsanCheckDynamicRTPrereqs() {
-  // Ensure that dynamic RT is the first DSO in the list
-  const char *first_dso_name = 0;
-  dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
-  if (first_dso_name && !IsDynamicRTName(first_dso_name)) {
-    Report("ASan runtime does not come first in initial library list; "
-           "you should either link runtime to your application or "
-           "manually preload it with LD_PRELOAD.\n");
-    Die();
-  }
-}
-
 void AsanCheckIncompatibleRT() {
   if (ASAN_DYNAMIC) {
     if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {

Reply via email to