[compiler-rt] 3142dff - [nfc][lsan] Extract significant part of the loop into a function (#112610)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 16 22:45:43 PDT 2024


Author: Vitaly Buka
Date: 2024-10-16T22:45:40-07:00
New Revision: 3142dff70401086a14ee9ae3428f65f5dfa6a2e6

URL: https://github.com/llvm/llvm-project/commit/3142dff70401086a14ee9ae3428f65f5dfa6a2e6
DIFF: https://github.com/llvm/llvm-project/commit/3142dff70401086a14ee9ae3428f65f5dfa6a2e6.diff

LOG: [nfc][lsan] Extract significant part of the loop into a function (#112610)

Co-authored-by: thetruestblue <92476612+thetruestblue at users.noreply.github.com>

Added: 
    

Modified: 
    compiler-rt/lib/lsan/lsan_common.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index a1a15bf98a1183..721db7872cce83 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -399,6 +399,112 @@ static void ProcessThreadRegistry(Frontier *frontier) {
 }
 
 // Scans thread data (stacks and TLS) for heap pointers.
+static void ProcessThread(tid_t os_id, uptr sp,
+                          const InternalMmapVector<uptr> &registers,
+                          InternalMmapVector<Range> &extra_ranges,
+                          Frontier *frontier) {
+  // `extra_ranges` is outside of the function and the loop to reused mapped
+  // memory.
+  CHECK(extra_ranges.empty());
+  LOG_THREADS("Processing thread %llu.\n", os_id);
+  uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end;
+  DTLS *dtls;
+  bool thread_found =
+      GetThreadRangesLocked(os_id, &stack_begin, &stack_end, &tls_begin,
+                            &tls_end, &cache_begin, &cache_end, &dtls);
+  if (!thread_found) {
+    // If a thread can't be found in the thread registry, it's probably in the
+    // process of destruction. Log this event and move on.
+    LOG_THREADS("Thread %llu not found in registry.\n", os_id);
+    return;
+  }
+
+  if (!sp)
+    sp = stack_begin;
+
+  if (flags()->use_registers) {
+    uptr registers_begin = reinterpret_cast<uptr>(registers.data());
+    uptr registers_end =
+        reinterpret_cast<uptr>(registers.data() + registers.size());
+    ScanRangeForPointers(registers_begin, registers_end, frontier, "REGISTERS",
+                         kReachable);
+  }
+
+  if (flags()->use_stacks) {
+    LOG_THREADS("Stack at %p-%p (SP = %p).\n", (void *)stack_begin,
+                (void *)stack_end, (void *)sp);
+    if (sp < stack_begin || sp >= stack_end) {
+      // SP is outside the recorded stack range (e.g. the thread is running a
+      // signal handler on alternate stack, or swapcontext was used).
+      // Again, consider the entire stack range to be reachable.
+      LOG_THREADS("WARNING: stack pointer not in stack range.\n");
+      uptr page_size = GetPageSizeCached();
+      int skipped = 0;
+      while (stack_begin < stack_end &&
+             !IsAccessibleMemoryRange(stack_begin, 1)) {
+        skipped++;
+        stack_begin += page_size;
+      }
+      LOG_THREADS("Skipped %d guard page(s) to obtain stack %p-%p.\n", skipped,
+                  (void *)stack_begin, (void *)stack_end);
+    } else {
+      // Shrink the stack range to ignore out-of-scope values.
+      stack_begin = sp;
+    }
+    ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK", kReachable);
+    GetThreadExtraStackRangesLocked(os_id, &extra_ranges);
+    ScanExtraStackRanges(extra_ranges, frontier);
+  }
+
+  if (flags()->use_tls) {
+    if (tls_begin) {
+      LOG_THREADS("TLS at %p-%p.\n", (void *)tls_begin, (void *)tls_end);
+      // If the tls and cache ranges don't overlap, scan full tls range,
+      // otherwise, only scan the non-overlapping portions
+      if (cache_begin == cache_end || tls_end < cache_begin ||
+          tls_begin > cache_end) {
+        ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
+      } else {
+        if (tls_begin < cache_begin)
+          ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
+                               kReachable);
+        if (tls_end > cache_end)
+          ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable);
+      }
+    }
+#    if SANITIZER_ANDROID
+    auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
+                   void *arg) -> void {
+      ScanRangeForPointers(
+          reinterpret_cast<uptr>(dtls_begin), reinterpret_cast<uptr>(dtls_end),
+          reinterpret_cast<Frontier *>(arg), "DTLS", kReachable);
+    };
+
+    // FIXME: There might be a race-condition here (and in Bionic) if the
+    // thread is suspended in the middle of updating its DTLS. IOWs, we
+    // could scan already freed memory. (probably fine for now)
+    __libc_iterate_dynamic_tls(os_id, cb, frontier);
+#    else
+    if (dtls && !DTLSInDestruction(dtls)) {
+      ForEachDVT(dtls, [&](const DTLS::DTV &dtv, int id) {
+        uptr dtls_beg = dtv.beg;
+        uptr dtls_end = dtls_beg + dtv.size;
+        if (dtls_beg < dtls_end) {
+          LOG_THREADS("DTLS %d at %p-%p.\n", id, (void *)dtls_beg,
+                      (void *)dtls_end);
+          ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS",
+                               kReachable);
+        }
+      });
+    } else {
+      // We are handling a thread with DTLS under destruction. Log about
+      // this and continue.
+      LOG_THREADS("Thread %llu has DTLS under destruction.\n", os_id);
+    }
+#    endif
+  }
+}
+
 static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
                            Frontier *frontier, tid_t caller_tid,
                            uptr caller_sp) {
@@ -408,7 +514,7 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
     registers.clear();
     extra_ranges.clear();
 
-    const tid_t os_id = static_cast<tid_t>(suspended_threads.GetThreadID(i));
+    const tid_t os_id = suspended_threads.GetThreadID(i);
     uptr sp = 0;
     PtraceRegistersStatus have_registers =
         suspended_threads.GetRegistersAndSP(i, &registers, &sp);
@@ -421,109 +527,10 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
       sp = 0;
     }
 
-    LOG_THREADS("Processing thread %llu.\n", os_id);
-    uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end;
-    DTLS *dtls;
-    bool thread_found =
-        GetThreadRangesLocked(os_id, &stack_begin, &stack_end, &tls_begin,
-                              &tls_end, &cache_begin, &cache_end, &dtls);
-    if (!thread_found) {
-      // If a thread can't be found in the thread registry, it's probably in the
-      // process of destruction. Log this event and move on.
-      LOG_THREADS("Thread %llu not found in registry.\n", os_id);
-      continue;
-    }
-
     if (os_id == caller_tid)
       sp = caller_sp;
 
-    if (!sp)
-      sp = stack_begin;
-
-    if (flags()->use_registers && have_registers) {
-      uptr registers_begin = reinterpret_cast<uptr>(registers.data());
-      uptr registers_end =
-          reinterpret_cast<uptr>(registers.data() + registers.size());
-      ScanRangeForPointers(registers_begin, registers_end, frontier,
-                           "REGISTERS", kReachable);
-    }
-
-    if (flags()->use_stacks) {
-      LOG_THREADS("Stack at %p-%p (SP = %p).\n", (void *)stack_begin,
-                  (void *)stack_end, (void *)sp);
-      if (sp < stack_begin || sp >= stack_end) {
-        // SP is outside the recorded stack range (e.g. the thread is running a
-        // signal handler on alternate stack, or swapcontext was used).
-        // Again, consider the entire stack range to be reachable.
-        LOG_THREADS("WARNING: stack pointer not in stack range.\n");
-        uptr page_size = GetPageSizeCached();
-        int skipped = 0;
-        while (stack_begin < stack_end &&
-               !IsAccessibleMemoryRange(stack_begin, 1)) {
-          skipped++;
-          stack_begin += page_size;
-        }
-        LOG_THREADS("Skipped %d guard page(s) to obtain stack %p-%p.\n",
-                    skipped, (void *)stack_begin, (void *)stack_end);
-      } else {
-        // Shrink the stack range to ignore out-of-scope values.
-        stack_begin = sp;
-      }
-      ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK",
-                           kReachable);
-      GetThreadExtraStackRangesLocked(os_id, &extra_ranges);
-      ScanExtraStackRanges(extra_ranges, frontier);
-    }
-
-    if (flags()->use_tls) {
-      if (tls_begin) {
-        LOG_THREADS("TLS at %p-%p.\n", (void *)tls_begin, (void *)tls_end);
-        // If the tls and cache ranges don't overlap, scan full tls range,
-        // otherwise, only scan the non-overlapping portions
-        if (cache_begin == cache_end || tls_end < cache_begin ||
-            tls_begin > cache_end) {
-          ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
-        } else {
-          if (tls_begin < cache_begin)
-            ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
-                                 kReachable);
-          if (tls_end > cache_end)
-            ScanRangeForPointers(cache_end, tls_end, frontier, "TLS",
-                                 kReachable);
-        }
-      }
-#    if SANITIZER_ANDROID
-      auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
-                     void *arg) -> void {
-        ScanRangeForPointers(reinterpret_cast<uptr>(dtls_begin),
-                             reinterpret_cast<uptr>(dtls_end),
-                             reinterpret_cast<Frontier *>(arg), "DTLS",
-                             kReachable);
-      };
-
-      // FIXME: There might be a race-condition here (and in Bionic) if the
-      // thread is suspended in the middle of updating its DTLS. IOWs, we
-      // could scan already freed memory. (probably fine for now)
-      __libc_iterate_dynamic_tls(os_id, cb, frontier);
-#    else
-      if (dtls && !DTLSInDestruction(dtls)) {
-        ForEachDVT(dtls, [&](const DTLS::DTV &dtv, int id) {
-          uptr dtls_beg = dtv.beg;
-          uptr dtls_end = dtls_beg + dtv.size;
-          if (dtls_beg < dtls_end) {
-            LOG_THREADS("DTLS %d at %p-%p.\n", id, (void *)dtls_beg,
-                        (void *)dtls_end);
-            ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS",
-                                 kReachable);
-          }
-        });
-      } else {
-        // We are handling a thread with DTLS under destruction. Log about
-        // this and continue.
-        LOG_THREADS("Thread %llu has DTLS under destruction.\n", os_id);
-      }
-#    endif
-    }
+    ProcessThread(os_id, sp, registers, extra_ranges, frontier);
   }
 
   // Add pointers reachable from ThreadContexts


        


More information about the llvm-commits mailing list