[compiler-rt] [compiler-rt] Write ASAN/TSAN reports to a global for crash reporting (PR #200526)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Sun May 31 22:11:52 PDT 2026


================
@@ -139,71 +139,100 @@ static const char *ExternalMopDesc(bool first, bool write) {
                : (write ? "Previous modifying" : "Previous read-only");
 }
 
-static void PrintMop(const ReportMop *mop, bool first) {
+#  define Output(...)                                            \
+    if (out) {                                                   \
+      int written = internal_snprintf(out, outlen, __VA_ARGS__); \
+      out += written;                                            \
+      outlen -= written;                                         \
+    } else {                                                     \
+      Printf(__VA_ARGS__);                                       \
+    }
+
+static void PrintMop(const ReportMop* mop, bool first, char* out = nullptr,
+                     size_t outlen = 0) {
   Decorator d;
   char thrbuf[kThreadBufSize];
-  Printf("%s", d.Access());
+
+  if (!out)
+    Printf("%s", d.Access());
+
   if (mop->external_tag == kExternalTagNone) {
-    Printf("  %s of size %d at %p by %s",
-           MopDesc(first, mop->write, mop->atomic), mop->size,
-           (void *)mop->addr, thread_name(thrbuf, mop->tid));
+    Output("  %s of size %d at %p by %s",
+           MopDesc(first, mop->write, mop->atomic), mop->size, (void*)mop->addr,
+           thread_name(thrbuf, mop->tid));
   } else {
     const char *object_type = GetObjectTypeFromTag(mop->external_tag);
     if (object_type == nullptr)
         object_type = "external object";
-    Printf("  %s access of %s at %p by %s",
-           ExternalMopDesc(first, mop->write), object_type,
-           (void *)mop->addr, thread_name(thrbuf, mop->tid));
+    Output("  %s access of %s at %p by %s", ExternalMopDesc(first, mop->write),
+           object_type, (void*)mop->addr, thread_name(thrbuf, mop->tid));
+  }
+
+  if (!out) {
+    PrintMutexSet(mop->mset);
+    Printf(":\n");
+    Printf("%s", d.Default());
+    PrintStack(mop->stack);
   }
-  PrintMutexSet(mop->mset);
-  Printf(":\n");
-  Printf("%s", d.Default());
-  PrintStack(mop->stack);
 }
 
-static void PrintLocation(const ReportLocation *loc) {
+static bool PrintLocation(const ReportLocation* loc, char* out = nullptr,
+                          size_t outlen = 0) {
   Decorator d;
   char thrbuf[kThreadBufSize];
   bool print_stack = false;
-  Printf("%s", d.Location());
+
+  if (!out)
+    Printf("%s", d.Location());
+
   if (loc->type == ReportLocationGlobal) {
     const DataInfo &global = loc->global;
-    if (global.size != 0)
-      Printf("  Location is global '%s' of size %zu at %p (%s+0x%zx)\n\n",
-             global.name, global.size, reinterpret_cast<void *>(global.start),
+    if (global.size != 0) {
+      Output("  Location is global '%s' of size %zu at %p (%s+0x%zx)\n\n",
+             global.name, global.size, reinterpret_cast<void*>(global.start),
              StripModuleName(global.module), global.module_offset);
-    else
-      Printf("  Location is global '%s' at %p (%s+0x%zx)\n\n", global.name,
-             reinterpret_cast<void *>(global.start),
+    } else {
+      Output("  Location is global '%s' at %p (%s+0x%zx)\n\n", global.name,
+             reinterpret_cast<void*>(global.start),
              StripModuleName(global.module), global.module_offset);
+    }
   } else if (loc->type == ReportLocationHeap) {
     char thrbuf[kThreadBufSize];
     const char *object_type = GetObjectTypeFromTag(loc->external_tag);
     if (!object_type) {
-      Printf("  Location is heap block of size %zu at %p allocated by %s:\n",
+      Output("  Location is heap block of size %zu at %p allocated by %s",
              loc->heap_chunk_size,
-             reinterpret_cast<void *>(loc->heap_chunk_start),
+             reinterpret_cast<void*>(loc->heap_chunk_start),
              thread_name(thrbuf, loc->tid));
     } else {
-      Printf("  Location is %s of size %zu at %p allocated by %s:\n",
-             object_type, loc->heap_chunk_size,
-             reinterpret_cast<void *>(loc->heap_chunk_start),
+      Output("  Location is %s of size %zu at %p allocated by %s", object_type,
+             loc->heap_chunk_size,
+             reinterpret_cast<void*>(loc->heap_chunk_start),
              thread_name(thrbuf, loc->tid));
     }
+    if (!out)
+      Printf(":\n");
     print_stack = true;
   } else if (loc->type == ReportLocationStack) {
-    Printf("  Location is stack of %s.\n\n", thread_name(thrbuf, loc->tid));
+    Output("  Location is stack of %s.\n\n", thread_name(thrbuf, loc->tid));
----------------
vitalybuka wrote:

Rename is unnececary 

https://github.com/llvm/llvm-project/pull/200526


More information about the llvm-commits mailing list