[clang] [sanitizer_symbolizer] Symbolizer Markup for linux (PR #66126)

Andres Villegas via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 12 12:25:56 PDT 2023


=?utf-8?q?Andrés?= Villegas <andresvi at google.com>,
=?utf-8?q?Andrés?= Villegas <andresvi at google.com>,
=?utf-8?q?Andrés?= Villegas <andresvi at google.com>,
=?utf-8?q?Andrés?= Villegas <andresvi at google.com>


https://github.com/avillega updated https://github.com/llvm/llvm-project/pull/66126:

>From 953a832b2e38d28d1b0e11ea3f5a2b05d69640b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andresvi at google.com>
Date: Thu, 10 Aug 2023 18:19:46 +0000
Subject: [PATCH 1/5] [sanitizer] Symbolizer Markup for linux.

This change adds support for sanitizer symbolizer markup
for linux. For more informationa about symbolzier markup
please visit https://llvm.org/docs/SymbolizerMarkupFormat.html
---
 compiler-rt/lib/hwasan/hwasan_report.cpp      |  44 ++++-
 .../lib/sanitizer_common/CMakeLists.txt       |   1 +
 .../lib/sanitizer_common/sanitizer_flags.inc  |   3 +
 .../sanitizer_stacktrace_libcdep.cpp          |  64 +++++-
 .../sanitizer_stacktrace_printer.cpp          |  31 ++-
 .../sanitizer_stacktrace_printer.h            |  10 +-
 .../sanitizer_common/sanitizer_symbolizer.h   |   5 +-
 .../sanitizer_symbolizer_internal.h           |   1 -
 .../sanitizer_symbolizer_libcdep.cpp          |  12 ++
 .../sanitizer_symbolizer_markup.cpp           | 186 +++++++++++++++---
 .../sanitizer_symbolizer_markup.h             |  69 +++++++
 .../sanitizer_symbolizer_posix_libcdep.cpp    |   7 +
 .../sanitizer_symbolizer_report.cpp           |   1 +
 .../sanitizer_stacktrace_printer_test.cpp     |  36 ++--
 compiler-rt/lib/tsan/rtl/tsan_report.cpp      |  10 +
 15 files changed, 413 insertions(+), 67 deletions(-)
 create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index efe6f57704919a4..9e8fe03510213af 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -248,6 +248,44 @@ static void PrintStackAllocations(StackAllocationsRingBuffer *sa,
     if (SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc)) {
       RenderFrame(&frame_desc, " %F %L", 0, frame->info.address, &frame->info,
                   common_flags()->symbolize_vs_style,
+                  common_flags()->enable_symbolizer_markup,
+                  common_flags()->strip_path_prefix);
+      frame->ClearAll();
+    }
+    Printf("%s\n", frame_desc.data());
+    frame_desc.clear();
+  }
+}
+
+
+static void PrintStackAllocationsMarkup(StackAllocationsRingBuffer *sa) {
+  // For symbolizer markup it is just necessary to have dump stack
+  // frames for offline symbolization.
+
+  uptr frames = Min((uptr)flags()->stack_history_size, sa->size());
+  if (const ListOfModules *modules =
+          Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
+    InternalScopedString modules_res;
+    RenderModules(&modules_res, modules,
+                  /*symbolizer_markup=*/ true);
+    Printf("%s", modules_res.data());
+  }
+
+  InternalScopedString frame_desc;
+  Printf("Previously allocated frames:\n");
+  for (uptr i = 0; i < frames; i++) {
+    const uptr *record_addr = &(*sa)[i];
+    uptr record = *record_addr;
+    if (!record)
+      break;
+    uptr pc_mask = (1ULL << 48) - 1;
+    uptr pc = record & pc_mask;
+    frame_desc.append("  record_addr:0x%zx record:0x%zx",
+                      reinterpret_cast<uptr>(record_addr), record);
+    if (SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc)) {
+      RenderFrame(&frame_desc, "", 0, frame->info.address, &frame->info,
+                  common_flags()->symbolize_vs_style,
+                  /*symbolizer_markup=*/ true,
                   common_flags()->strip_path_prefix);
       frame->ClearAll();
     }
@@ -425,7 +463,11 @@ void PrintAddressDescription(
       auto *sa = (t == GetCurrentThread() && current_stack_allocations)
                      ? current_stack_allocations
                      : t->stack_allocations();
-      PrintStackAllocations(sa, addr_tag, untagged_addr);
+      if (common_flags()->enable_symbolizer_markup) {
+        PrintStackAllocations(sa, addr_tag, untagged_addr);
+      } else {
+        PrintStackAllocationsMarkup(sa);
+      }
       num_descriptions_printed++;
     }
   });
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index d8517f3de06a493..de398edea32753b 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -191,6 +191,7 @@ set(SANITIZER_IMPL_HEADERS
   sanitizer_symbolizer_internal.h
   sanitizer_symbolizer_libbacktrace.h
   sanitizer_symbolizer_mac.h
+  sanitizer_symbolizer_markup.h
   sanitizer_syscall_generic.inc
   sanitizer_syscall_linux_aarch64.inc
   sanitizer_syscall_linux_arm.inc
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
index 6148ae56067cae0..a83c2fafe48a6e6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
@@ -269,3 +269,6 @@ COMMON_FLAG(bool, detect_write_exec, false,
 COMMON_FLAG(bool, test_only_emulate_no_memorymap, false,
             "TEST ONLY fail to read memory mappings to emulate sanitized "
             "\"init\"")
+COMMON_FLAG(bool, enable_symbolizer_markup, false,
+            "Use sanitizer symbolizer "
+            "markup, available only on Linux and Fuchsia.")
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
index 47983ee7ec713f2..6a6da22c2e3e12e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
@@ -11,10 +11,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common.h"
+#include "sanitizer_flags.h"
 #include "sanitizer_placement_new.h"
 #include "sanitizer_stacktrace.h"
 #include "sanitizer_stacktrace_printer.h"
 #include "sanitizer_symbolizer.h"
+#include "sanitizer_symbolizer_markup.h"
 
 namespace __sanitizer {
 
@@ -26,10 +28,10 @@ class StackTraceTextPrinter {
                         InternalScopedString *output,
                         InternalScopedString *dedup_token)
       : stack_trace_fmt_(stack_trace_fmt),
-        frame_delimiter_(frame_delimiter),
-        output_(output),
         dedup_token_(dedup_token),
-        symbolize_(RenderNeedsSymbolization(stack_trace_fmt)) {}
+        symbolize_(RenderNeedsSymbolization(stack_trace_fmt, false)),
+        frame_delimiter_(frame_delimiter),
+        output_(output) {}
 
   bool ProcessAddressFrames(uptr pc) {
     SymbolizedStack *frames = symbolize_
@@ -43,6 +45,7 @@ class StackTraceTextPrinter {
       RenderFrame(output_, stack_trace_fmt_, frame_num_++, cur->info.address,
                   symbolize_ ? &cur->info : nullptr,
                   common_flags()->symbolize_vs_style,
+                  common_flags()->enable_symbolizer_markup,
                   common_flags()->strip_path_prefix);
 
       if (prev_len != output_->length())
@@ -69,12 +72,45 @@ class StackTraceTextPrinter {
   }
 
   const char *stack_trace_fmt_;
-  const char frame_delimiter_;
   int dedup_frames_ = common_flags()->dedup_token_length;
-  uptr frame_num_ = 0;
-  InternalScopedString *output_;
   InternalScopedString *dedup_token_;
   const bool symbolize_ = false;
+
+ protected:
+  uptr frame_num_ = 0;
+  const char frame_delimiter_;
+  InternalScopedString *output_;
+};
+
+class StackTraceMarkupPrinter : public StackTraceTextPrinter {
+ public:
+  StackTraceMarkupPrinter(InternalScopedString *output)
+      : StackTraceTextPrinter("", '\n', output, nullptr){};
+
+  bool ProcessAddressFrames(uptr pc) {
+    SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
+
+    if (!frames)
+      return false;
+
+    if (const ListOfModules *modules =
+            Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
+      RenderModulesMarkup(output_, modules);
+    }
+
+    for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
+      uptr prev_len = output_->length();
+      RenderFrame(output_, "", frame_num_++, cur->info.address, nullptr,
+                  common_flags()->symbolize_vs_style,
+                  /*symbolizer_markup=*/true,
+                  common_flags()->strip_path_prefix);
+
+      if (prev_len != output_->length())
+        output_->append("%c", frame_delimiter_);
+    }
+    frames->ClearAll();
+    return true;
+  }
 };
 
 static void CopyStringToBuffer(const InternalScopedString &str, char *out_buf,
@@ -94,8 +130,11 @@ void StackTrace::PrintTo(InternalScopedString *output) const {
   CHECK(output);
 
   InternalScopedString dedup_token;
-  StackTraceTextPrinter printer(common_flags()->stack_trace_format, '\n',
-                                output, &dedup_token);
+  StackTraceTextPrinter printer =
+      common_flags()->enable_symbolizer_markup
+          ? StackTraceMarkupPrinter(output)
+          : StackTraceTextPrinter(common_flags()->stack_trace_format, '\n',
+                                  output, &dedup_token);
 
   if (trace == nullptr || size == 0) {
     output->append("    <empty stack>\n\n");
@@ -194,7 +233,11 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
   pc = StackTrace::GetPreviousInstructionPc(pc);
 
   InternalScopedString output;
-  StackTraceTextPrinter printer(fmt, '\0', &output, nullptr);
+  StackTraceTextPrinter printer =
+      common_flags()->enable_symbolizer_markup
+          ? StackTraceMarkupPrinter(&output)
+          : StackTraceTextPrinter(fmt, '\0', &output, nullptr);
+
   if (!printer.ProcessAddressFrames(pc)) {
     output.clear();
     output.append("<can't symbolize>");
@@ -210,7 +253,8 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt,
   DataInfo DI;
   if (!Symbolizer::GetOrInit()->SymbolizeData(data_addr, &DI)) return;
   InternalScopedString data_desc;
-  RenderData(&data_desc, fmt, &DI, common_flags()->strip_path_prefix);
+  RenderData(&data_desc, fmt, &DI, common_flags()->enable_symbolizer_markup,
+             common_flags()->strip_path_prefix);
   internal_strncpy(out_buf, data_desc.data(), out_buf_size);
   out_buf[out_buf_size - 1] = 0;
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
index 45c480d225c7f5a..b29e688b214c6ed 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
@@ -14,7 +14,7 @@
 
 #include "sanitizer_file.h"
 #include "sanitizer_flags.h"
-#include "sanitizer_fuchsia.h"
+#include "sanitizer_symbolizer_markup.h"
 
 namespace __sanitizer {
 
@@ -143,7 +143,12 @@ static const char kDefaultFormat[] = "    #%n %p %F %L";
 
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
-                 const char *strip_path_prefix) {
+                 bool symbolizer_markup, const char *strip_path_prefix) {
+  if (symbolizer_markup) {
+    RenderFrameMarkup(buffer, format, frame_no, address, info, vs_style,
+                      strip_path_prefix);
+    return;
+  }
   // info will be null in the case where symbolization is not needed for the
   // given format. This ensures that the code below will get a hard failure
   // rather than print incorrect information in case RenderNeedsSymbolization
@@ -250,7 +255,11 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
   }
 }
 
-bool RenderNeedsSymbolization(const char *format) {
+bool RenderNeedsSymbolization(const char *format, bool symbolizer_markup) {
+  if (symbolizer_markup) {
+    // Online symbolization is never needed for symbolizer markup.
+    return false;
+  }
   if (0 == internal_strcmp(format, "DEFAULT"))
     format = kDefaultFormat;
   for (const char *p = format; *p != '\0'; p++) {
@@ -274,7 +283,12 @@ bool RenderNeedsSymbolization(const char *format) {
 }
 
 void RenderData(InternalScopedString *buffer, const char *format,
-                const DataInfo *DI, const char *strip_path_prefix) {
+                const DataInfo *DI, bool symbolizer_markup,
+                const char *strip_path_prefix) {
+  if (symbolizer_markup) {
+    RenderDataMarkup(buffer, format, DI, strip_path_prefix);
+    return;
+  }
   for (const char *p = format; *p != '\0'; p++) {
     if (*p != '%') {
       buffer->append("%c", *p);
@@ -333,4 +347,13 @@ void RenderModuleLocation(InternalScopedString *buffer, const char *module,
   buffer->append("+0x%zx)", offset);
 }
 
+void RenderModules(InternalScopedString *buffer, const ListOfModules *modules,
+                   bool symbolizer_markup) {
+  // Rendering all the modules is only needed for symbolizer markup
+  if (!symbolizer_markup)
+    return;
+
+  RenderModulesMarkup(buffer, modules);
+}
+
 } // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
index bf2755a2e8f458d..f514feada1f59be 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -50,9 +50,9 @@ const char *StripFunctionName(const char *function);
 //   %M - prints module basename and offset, if it is known, or PC.
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
-                 const char *strip_path_prefix = "");
+                 bool symbolizer_markup, const char *strip_path_prefix = "");
 
-bool RenderNeedsSymbolization(const char *format);
+bool RenderNeedsSymbolization(const char *format, bool symbolizer_markup);
 
 void RenderSourceLocation(InternalScopedString *buffer, const char *file,
                           int line, int column, bool vs_style,
@@ -67,7 +67,11 @@ void RenderModuleLocation(InternalScopedString *buffer, const char *module,
 // Also accepts:
 //   %g - name of the global variable.
 void RenderData(InternalScopedString *buffer, const char *format,
-                const DataInfo *DI, const char *strip_path_prefix = "");
+                const DataInfo *DI, bool symbolizer_markup,
+                const char *strip_path_prefix = "");
+
+void RenderModules(InternalScopedString *buffer, const ListOfModules *modules,
+                   bool symbolizer_markup);
 
 }  // namespace __sanitizer
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
index df24aaca3abf645..4006b69291df7bc 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
@@ -20,7 +20,6 @@
 
 #include "sanitizer_common.h"
 #include "sanitizer_mutex.h"
-#include "sanitizer_vector.h"
 
 namespace __sanitizer {
 
@@ -154,6 +153,10 @@ class Symbolizer final {
 
   void InvalidateModuleList();
 
+  // returns the list of modules if it was refreshed
+  // otherwise returns nullptr.
+  const ListOfModules *GetRefreshedListOfModules();
+
  private:
   // GetModuleNameAndOffsetForPC has to return a string to the caller.
   // Since the corresponding module might get unloaded later, we should create
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h
index 3ec4d80105a245a..fce98bfabdbeb0c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h
@@ -15,7 +15,6 @@
 
 #include "sanitizer_file.h"
 #include "sanitizer_symbolizer.h"
-#include "sanitizer_vector.h"
 
 namespace __sanitizer {
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index a6f82ced2036731..aa5523ce36949a6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -11,9 +11,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_allocator_internal.h"
+#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
 #include "sanitizer_internal_defs.h"
 #include "sanitizer_platform.h"
 #include "sanitizer_symbolizer_internal.h"
+#include "sanitizer_symbolizer_markup.h"
 
 namespace __sanitizer {
 
@@ -188,6 +191,15 @@ void Symbolizer::RefreshModules() {
   modules_fresh_ = true;
 }
 
+const ListOfModules *Symbolizer::GetRefreshedListOfModules() {
+  if (!modules_fresh_) {
+    RefreshModules();
+  }
+
+  CHECK(modules_fresh_);
+  return &modules_;
+}
+
 static const LoadedModule *SearchForModule(const ListOfModules &modules,
                                            uptr address) {
   for (uptr i = 0; i < modules.size(); i++) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
index c8c10de10d03a24..a96bcb0e88b31c4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -11,20 +11,140 @@
 // Implementation of offline markup symbolizer.
 //===----------------------------------------------------------------------===//
 
-#include "sanitizer_platform.h"
-#if SANITIZER_SYMBOLIZER_MARKUP
+#include "sanitizer_symbolizer_markup.h"
 
-#if SANITIZER_FUCHSIA
+#include "sanitizer_common.h"
+#include "sanitizer_libc.h"
+#include "sanitizer_platform.h"
+#include "sanitizer_stacktrace.h"
+#include "sanitizer_symbolizer.h"
 #include "sanitizer_symbolizer_fuchsia.h"
-#  endif
 
-#  include <limits.h>
-#  include <unwind.h>
+namespace __sanitizer {
 
-#  include "sanitizer_stacktrace.h"
-#  include "sanitizer_symbolizer.h"
+void RenderDataMarkup(InternalScopedString *buffer, const char *format,
+                      const DataInfo *DI, const char *strip_path_prefix) {
+  buffer->append(kFormatData, DI->start);
+}
 
-namespace __sanitizer {
+bool RenderNeedsSymbolizationMarkup(const char *format) { return false; }
+
+void RenderFrameMarkup(InternalScopedString *buffer, const char *format,
+                       int frame_no, uptr address, const AddressInfo *info,
+                       bool vs_style, const char *strip_path_prefix) {
+  CHECK(!RenderNeedsSymbolizationMarkup(format));
+  buffer->append(kFormatFrame, frame_no, address);
+}
+
+// Simplier view of a LoadedModule. It only holds information necessary to
+// identify unique modules.
+struct RenderedModule {
+  char *full_name;
+  u8 uuid[kModuleUUIDSize];  // BuildId
+  uptr base_address;
+};
+
+bool ModulesEq(const LoadedModule *module,
+               const RenderedModule *renderedModule) {
+  return module->base_address() == renderedModule->base_address &&
+         internal_memcmp(module->uuid(), renderedModule->uuid,
+                         module->uuid_size()) == 0 &&
+         internal_strcmp(module->full_name(), renderedModule->full_name) == 0;
+}
+
+bool ModuleHasBeenRendered(
+    const LoadedModule *module,
+    const InternalMmapVectorNoCtor<RenderedModule> *renderedModules) {
+  for (auto *it = renderedModules->begin(); it != renderedModules->end();
+       ++it) {
+    const auto &renderedModule = *it;
+    if (ModulesEq(module, &renderedModule)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void RenderModulesMarkup(InternalScopedString *buffer,
+                         const ListOfModules *modules) {
+  // Keeps track of the modules that have been rendered.
+  static bool initialized = false;
+  static InternalMmapVectorNoCtor<RenderedModule> renderedModules;
+  if (!initialized) {
+    renderedModules.Initialize(modules->size());
+    initialized = true;
+  }
+
+  if (!renderedModules.size()) {
+    buffer->append("{{{reset}}}\n");
+  }
+
+  for (auto *moduleIt = modules->begin(); moduleIt != modules->end();
+       ++moduleIt) {
+    const LoadedModule &module = *moduleIt;
+
+    if (ModuleHasBeenRendered(&module, &renderedModules)) {
+      continue;
+    }
+
+    buffer->append("{{{module:%d:%s:elf:", renderedModules.size(),
+                   module.full_name());
+    for (uptr i = 0; i < module.uuid_size(); i++) {
+      buffer->append("%02x", module.uuid()[i]);
+    }
+    buffer->append("}}}\n");
+
+    const auto ranges = module.ranges();
+    for (const auto &range : ranges) {
+      buffer->append("{{{mmap:%p:%p:load:%d:r", range.beg,
+                     range.end - range.beg, renderedModules.size());
+      if (range.writable)
+        buffer->append("w");
+      if (range.executable)
+        buffer->append("x");
+
+      // module.base_address = dlpi_addr
+      // range.beg = dlpi_addr + p_vaddr
+      // relative address = p_vaddr = range.beg - module.base_address
+      buffer->append(":%p}}}\n", range.beg - module.base_address());
+    }
+
+    renderedModules.push_back({});
+    RenderedModule &curModule = renderedModules.back();
+    curModule.full_name = internal_strdup(module.full_name());
+    internal_memcpy(curModule.uuid, module.uuid(), module.uuid_size());
+    curModule.base_address = module.base_address();
+  }
+}
+
+MarkupSymbolizer *MarkupSymbolizer::get(LowLevelAllocator *alloc) {
+  return new (*alloc) MarkupSymbolizer();
+}
+
+bool MarkupSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
+  char buffer[kFormatFunctionMax];
+  internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr);
+  stack->info.function = internal_strdup(buffer);
+  return true;
+}
+
+bool MarkupSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
+  info->Clear();
+  info->start = addr;
+  return true;
+}
+
+// This is used by UBSan for type names, and by ASan for global variable names.
+// It's expected to return a static buffer that will be reused on each call.
+const char *MarkupSymbolizer::Demangle(const char *name) {
+  static char buffer[kFormatDemangleMax];
+  internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name);
+  return buffer;
+}
+
+#if SANITIZER_SYMBOLIZER_MARKUP
+#  include <limits.h>
+#  include <unwind.h>
 
 // This generic support for offline symbolizing is based on the
 // Fuchsia port.  We don't do any actual symbolization per se.
@@ -38,9 +158,9 @@ namespace __sanitizer {
 // This is used by UBSan for type names, and by ASan for global variable names.
 // It's expected to return a static buffer that will be reused on each call.
 const char *Symbolizer::Demangle(const char *name) {
-  static char buffer[kFormatDemangleMax];
-  internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name);
-  return buffer;
+  SymbolizerTool *markupSymbolizer = tools_.front();
+  CHECK(markupSymbolizer);
+  return markupSymbolizer->Demangle(name);
 }
 
 // This is used mostly for suppression matching.  Making it work
@@ -66,38 +186,45 @@ bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { return false; }
 // to render stack frames, but that should be changed to use
 // RenderStackFrame.
 SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) {
+  SymbolizerTool *markupSymbolizer = tools_.front();
+  CHECK(markupSymbolizer);
+
   SymbolizedStack *s = SymbolizedStack::New(addr);
-  char buffer[kFormatFunctionMax];
-  internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr);
-  s->info.function = internal_strdup(buffer);
+  markupSymbolizer->SymbolizePC(addr, s);
   return s;
 }
 
 // Always claim we succeeded, so that RenderDataInfo will be called.
 bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
-  info->Clear();
-  info->start = addr;
-  return true;
+  SymbolizerTool *markupSymbolizer = tools_.front();
+  CHECK(markupSymbolizer);
+  return markupSymbolizer->SymbolizeData(addr, info);
 }
 
 // We ignore the format argument to __sanitizer_symbolize_global.
 void RenderData(InternalScopedString *buffer, const char *format,
-                const DataInfo *DI, const char *strip_path_prefix) {
-  buffer->append(kFormatData, DI->start);
+                const DataInfo *DI, bool symbolizer_markup,
+                const char *strip_path_prefix) {
+  RenderDataMarkup(buffer, format, DI, strip_path_prefix);
 }
 
-bool RenderNeedsSymbolization(const char *format) { return false; }
+bool RenderNeedsSymbolization(const char *format, bool symbolizer_markup) {
+  return RenderNeedsSymbolizationMarkup(format);
+}
 
 // We don't support the stack_trace_format flag at all.
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
                  const char *strip_path_prefix) {
-  CHECK(!RenderNeedsSymbolization(format));
-  buffer->append(kFormatFrame, frame_no, address);
+  RenderFrameMarkup(buffer, format, frame_no, address, info, vs_style,
+                    strip_path_prefix);
 }
 
 Symbolizer *Symbolizer::PlatformInit() {
-  return new (symbolizer_allocator_) Symbolizer({});
+  IntrusiveList<SymbolizerTool> tools;
+  SymbolizerTool *tool = MarkupSymbolizer::get(&symbolizer_allocator_);
+  tools.push_back(tool);
+  return new (symbolizer_allocator_) Symbolizer(tools);
 }
 
 void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); }
@@ -107,7 +234,7 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                         UnwindSignalStackCallbackType unwind,
                         const void *unwind_context) {}
 
-#if SANITIZER_CAN_SLOW_UNWIND
+#  if SANITIZER_CAN_SLOW_UNWIND
 struct UnwindTraceArg {
   BufferedStackTrace *stack;
   u32 max_depth;
@@ -117,7 +244,8 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
   UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
   CHECK_LT(arg->stack->size, arg->max_depth);
   uptr pc = _Unwind_GetIP(ctx);
-  if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
+  if (pc < PAGE_SIZE)
+    return _URC_NORMAL_STOP;
   arg->stack->trace_buffer[arg->stack->size++] = pc;
   return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
                                              : _URC_NO_REASON);
@@ -143,8 +271,8 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
   CHECK_GE(max_depth, 2);
   UNREACHABLE("signal context doesn't exist");
 }
-#endif  // SANITIZER_CAN_SLOW_UNWIND
-
-}  // namespace __sanitizer
+#  endif  // SANITIZER_CAN_SLOW_UNWIND
 
 #endif  // SANITIZER_SYMBOLIZER_MARKUP
+
+}  // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
new file mode 100644
index 000000000000000..a09278c30bbd216
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
@@ -0,0 +1,69 @@
+//===-- sanitizer_symbolizer_markup.h -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries.
+//
+// Definitions of the offline markup symbolizer.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_SYMBOLIZER_MARKUP_H
+#define SANITIZER_SYMBOLIZER_MARKUP_H
+
+#include "sanitizer_common.h"
+#include "sanitizer_symbolizer.h"
+#include "sanitizer_symbolizer_internal.h"
+
+namespace __sanitizer {
+
+// This generic support for offline symbolizing is based on the
+// Fuchsia port.  We don't do any actual symbolization per se.
+// Instead, we emit text containing raw addresses and raw linkage
+// symbol names, embedded in Fuchsia's symbolization markup format.
+// Fuchsia's logging infrastructure emits enough information about
+// process memory layout that a post-processing filter can do the
+// symbolization and pretty-print the markup.  See the spec at:
+// https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md
+
+class MarkupSymbolizer final : public SymbolizerTool {
+ public:
+  static MarkupSymbolizer *get(LowLevelAllocator *alloc);
+
+  // This is used in some places for suppression checking, which we
+  // don't really support for Fuchsia.  It's also used in UBSan to
+  // identify a PC location to a function name, so we always fill in
+  // the function member with a string containing markup around the PC
+  // value.
+  // TODO(mcgrathr): Under SANITIZER_GO, it's currently used by TSan
+  // to render stack frames, but that should be changed to use
+  // RenderStackFrame.
+  bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
+
+  // Always claim we succeeded, so that RenderDataInfo will be called.
+  bool SymbolizeData(uptr addr, DataInfo *info) override;
+
+  // May return NULL if demangling failed.
+  // This is used by UBSan for type names, and by ASan for global variable
+  // names. It's expected to return a static buffer that will be reused on each
+  // call.
+  const char *Demangle(const char *name) override;
+};
+
+// We ignore the format argument to __sanitizer_symbolize_global.
+void RenderDataMarkup(InternalScopedString *, const char *, const DataInfo *,
+                      const char *);
+
+bool RenderNeedsSymbolizationMarkup(const char *format);
+
+// We don't support the stack_trace_format flag at all.
+void RenderFrameMarkup(InternalScopedString *, const char *, int, uptr,
+                       const AddressInfo *, bool, const char *);
+
+void RenderModulesMarkup(InternalScopedString *, const ListOfModules *);
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_SYMBOLIZER_MARKUP_H
\ No newline at end of file
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index 1a5e38faea88747..c1f89d652904e50 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -32,6 +32,7 @@
 #  include "sanitizer_symbolizer_internal.h"
 #  include "sanitizer_symbolizer_libbacktrace.h"
 #  include "sanitizer_symbolizer_mac.h"
+#  include "sanitizer_symbolizer_markup.h"
 
 // C++ demangling function, as required by Itanium C++ ABI. This is weak,
 // because we do not require a C++ ABI library to be linked to a program
@@ -470,6 +471,12 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
     VReport(2, "Symbolizer is disabled.\n");
     return;
   }
+  if (common_flags()->enable_symbolizer_markup) {
+    VReport(2, "Using symbolizer markup.\n");
+    SymbolizerTool *tool = MarkupSymbolizer::get(allocator);
+    list->push_back(tool);
+    return;
+  }
   if (IsAllocatorOutOfMemory()) {
     VReport(2, "Cannot use internal symbolizer: out of memory\n");
   } else if (SymbolizerTool *tool = InternalSymbolizer::get(allocator)) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
index 73915715c5ba2c0..7fd21b90ecf62bd 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
@@ -35,6 +35,7 @@ void ReportErrorSummary(const char *error_type, const AddressInfo &info,
   buff.append("%s ", error_type);
   RenderFrame(&buff, "%L %F", 0, info.address, &info,
               common_flags()->symbolize_vs_style,
+              common_flags()->enable_symbolizer_markup,
               common_flags()->strip_path_prefix);
   ReportErrorSummary(buff.data(), alt_tool_name);
 }
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
index 489ef4dbb5b7d4c..96c7571574f4c9b 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
@@ -84,7 +84,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
               "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
               "Function:%f FunctionOffset:%q Source:%s Line:%l "
               "Column:%c",
-              frame_no, info.address, &info, false, "/path/to/");
+              frame_no, info.address, &info, false, false, "/path/to/");
   EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
                "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
                "Column:5",
@@ -97,7 +97,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
               "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
               "Function:%f FunctionOffset:%q Source:%s Line:%l "
               "Column:%c",
-              frame_no, info.address, &info, false, "/path/to/");
+              frame_no, info.address, &info, false, false, "/path/to/");
   EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
                "Function:bar FunctionOffset:0x100 Source:my/source Line:10 "
                "Column:5",
@@ -107,26 +107,26 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
 
   // Test special format specifiers.
   info.address = 0x400000;
-  RenderFrame(&str, "%M", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%M", frame_no, info.address, &info, false, false);
   EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
   str.clear();
 
-  RenderFrame(&str, "%L", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%L", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("(<unknown module>)", str.data());
   str.clear();
 
   info.module = internal_strdup("/path/to/module");
   info.module_offset = 0x200;
-  RenderFrame(&str, "%M", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%M", frame_no, info.address, &info, false, false);
   EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
   EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
   str.clear();
 
-  RenderFrame(&str, "%L", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%L", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("(/path/to/module+0x200)", str.data());
   str.clear();
 
-  RenderFrame(&str, "%b", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%b", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("", str.data());
   str.clear();
 
@@ -134,7 +134,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
   info.uuid[0] = 0x55;
   info.uuid[1] = 0x66;
 
-  RenderFrame(&str, "%M", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%M", frame_no, info.address, &info, false, false);
   EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
   EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
 #if SANITIZER_APPLE
@@ -144,7 +144,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
 #endif
   str.clear();
 
-  RenderFrame(&str, "%L", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%L", frame_no, info.address, &info, false, false);
 #if SANITIZER_APPLE
   EXPECT_STREQ("(/path/to/module+0x200)", str.data());
 #else
@@ -152,46 +152,46 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
 #endif
   str.clear();
 
-  RenderFrame(&str, "%b", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%b", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("(BuildId: 5566)", str.data());
   str.clear();
 
   info.function = internal_strdup("my_function");
-  RenderFrame(&str, "%F", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%F", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("in my_function", str.data());
   str.clear();
 
   info.function_offset = 0x100;
-  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("in my_function+0x100 <null>", str.data());
   str.clear();
 
   info.file = internal_strdup("my_file");
-  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("in my_function my_file", str.data());
   str.clear();
 
   info.line = 10;
-  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%F %S", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("in my_function my_file:10", str.data());
   str.clear();
 
   info.column = 5;
-  RenderFrame(&str, "%S %L", frame_no, info.address, &info, false);
+  RenderFrame(&str, "%S %L", frame_no, info.address, &info, false, false);
   EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
   str.clear();
 
-  RenderFrame(&str, "%S %L", frame_no, info.address, &info, true);
+  RenderFrame(&str, "%S %L", frame_no, info.address, &info, true, false);
   EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
   str.clear();
 
   info.column = 0;
-  RenderFrame(&str, "%F %S", frame_no, info.address, &info, true);
+  RenderFrame(&str, "%F %S", frame_no, info.address, &info, true, false);
   EXPECT_STREQ("in my_function my_file(10)", str.data());
   str.clear();
 
   info.line = 0;
-  RenderFrame(&str, "%F %S", frame_no, info.address, &info, true);
+  RenderFrame(&str, "%F %S", frame_no, info.address, &info, true, false);
   EXPECT_STREQ("in my_function my_file", str.data());
   str.clear();
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
index 3ae666e1212f72c..c31b30d98ae34b7 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
@@ -103,12 +103,22 @@ void PrintStack(const ReportStack *ent) {
     Printf("    [failed to restore the stack]\n\n");
     return;
   }
+
+  if (const ListOfModules *modules =
+          Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
+    InternalScopedString modules_res;
+    RenderModules(&modules_res, modules,
+                  common_flags()->enable_symbolizer_markup);
+    Printf("%s", modules_res.data());
+  }
+
   SymbolizedStack *frame = ent->frames;
   for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
     InternalScopedString res;
     RenderFrame(&res, common_flags()->stack_trace_format, i,
                 frame->info.address, &frame->info,
                 common_flags()->symbolize_vs_style,
+                common_flags()->enable_symbolizer_markup,
                 common_flags()->strip_path_prefix);
     Printf("%s\n", res.data());
   }

>From 2863cef6656f0c222464a1f67a65f63f57a8ab72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andresvi at google.com>
Date: Fri, 8 Sep 2023 19:46:52 +0000
Subject: [PATCH 2/5] Fix review comments

---
 compiler-rt/lib/hwasan/hwasan_report.cpp          | 11 +++++------
 .../sanitizer_stacktrace_printer.cpp              |  9 ---------
 .../sanitizer_stacktrace_printer.h                |  3 ---
 .../sanitizer_symbolizer_markup.cpp               |  5 +++++
 compiler-rt/lib/tsan/rtl/tsan_report.cpp          | 15 +++++++++------
 5 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 9e8fe03510213af..a91adbbad911325 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -30,6 +30,7 @@
 #include "sanitizer_common/sanitizer_stackdepot.h"
 #include "sanitizer_common/sanitizer_stacktrace_printer.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
+#include "sanitizer_common/sanitizer_symbolizer_markup.h"
 
 using namespace __sanitizer;
 
@@ -263,11 +264,11 @@ static void PrintStackAllocationsMarkup(StackAllocationsRingBuffer *sa) {
   // frames for offline symbolization.
 
   uptr frames = Min((uptr)flags()->stack_history_size, sa->size());
+
   if (const ListOfModules *modules =
           Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
     InternalScopedString modules_res;
-    RenderModules(&modules_res, modules,
-                  /*symbolizer_markup=*/ true);
+    RenderModulesMarkup(&modules_res, modules);
     Printf("%s", modules_res.data());
   }
 
@@ -280,8 +281,6 @@ static void PrintStackAllocationsMarkup(StackAllocationsRingBuffer *sa) {
       break;
     uptr pc_mask = (1ULL << 48) - 1;
     uptr pc = record & pc_mask;
-    frame_desc.append("  record_addr:0x%zx record:0x%zx",
-                      reinterpret_cast<uptr>(record_addr), record);
     if (SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc)) {
       RenderFrame(&frame_desc, "", 0, frame->info.address, &frame->info,
                   common_flags()->symbolize_vs_style,
@@ -464,9 +463,9 @@ void PrintAddressDescription(
                      ? current_stack_allocations
                      : t->stack_allocations();
       if (common_flags()->enable_symbolizer_markup) {
-        PrintStackAllocations(sa, addr_tag, untagged_addr);
-      } else {
         PrintStackAllocationsMarkup(sa);
+      } else {
+        PrintStackAllocations(sa, addr_tag, untagged_addr);
       }
       num_descriptions_printed++;
     }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
index b29e688b214c6ed..911d4f95810e6f3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
@@ -347,13 +347,4 @@ void RenderModuleLocation(InternalScopedString *buffer, const char *module,
   buffer->append("+0x%zx)", offset);
 }
 
-void RenderModules(InternalScopedString *buffer, const ListOfModules *modules,
-                   bool symbolizer_markup) {
-  // Rendering all the modules is only needed for symbolizer markup
-  if (!symbolizer_markup)
-    return;
-
-  RenderModulesMarkup(buffer, modules);
-}
-
 } // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
index f514feada1f59be..f2674cecaf6390b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -70,9 +70,6 @@ void RenderData(InternalScopedString *buffer, const char *format,
                 const DataInfo *DI, bool symbolizer_markup,
                 const char *strip_path_prefix = "");
 
-void RenderModules(InternalScopedString *buffer, const ListOfModules *modules,
-                   bool symbolizer_markup);
-
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_STACKTRACE_PRINTER_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
index a96bcb0e88b31c4..c8473b614e7e117 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -14,6 +14,7 @@
 #include "sanitizer_symbolizer_markup.h"
 
 #include "sanitizer_common.h"
+#include "sanitizer_internal_defs.h"
 #include "sanitizer_libc.h"
 #include "sanitizer_platform.h"
 #include "sanitizer_stacktrace.h"
@@ -112,7 +113,11 @@ void RenderModulesMarkup(InternalScopedString *buffer,
     renderedModules.push_back({});
     RenderedModule &curModule = renderedModules.back();
     curModule.full_name = internal_strdup(module.full_name());
+
+    // kModuleUUIDSize is the size of curModule.uuid
+    CHECK_GE(kModuleUUIDSize, module.uuid_size());
     internal_memcpy(curModule.uuid, module.uuid(), module.uuid_size());
+
     curModule.base_address = module.base_address();
   }
 }
diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
index c31b30d98ae34b7..0579fadb27caae9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
@@ -12,10 +12,12 @@
 #include "tsan_report.h"
 #include "tsan_platform.h"
 #include "tsan_rtl.h"
+
 #include "sanitizer_common/sanitizer_file.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stacktrace_printer.h"
+#include "sanitizer_common/sanitizer_symbolizer_markup.h"
 
 namespace __tsan {
 
@@ -104,12 +106,13 @@ void PrintStack(const ReportStack *ent) {
     return;
   }
 
-  if (const ListOfModules *modules =
-          Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
-    InternalScopedString modules_res;
-    RenderModules(&modules_res, modules,
-                  common_flags()->enable_symbolizer_markup);
-    Printf("%s", modules_res.data());
+  if (common_flags()->enable_symbolizer_markup) {
+    if (const ListOfModules *modules =
+            Symbolizer::GetOrInit()->GetRefreshedListOfModules()) {
+      InternalScopedString modules_res;
+      RenderModulesMarkup(&modules_res, modules);
+      Printf("%s", modules_res.data());
+    }
   }
 
   SymbolizedStack *frame = ent->frames;

>From 00051aaeccdf291b4b7fc3990f8516c5f2c31c4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andresvi at google.com>
Date: Tue, 12 Sep 2023 16:59:57 +0000
Subject: [PATCH 3/5] Add test for symbolizer markup

---
 .../sanitizer_stacktrace_libcdep.cpp          | 53 ++++++++++---------
 .../sanitizer_symbolizer_markup.cpp           |  9 +---
 .../sanitizer_symbolizer_markup.h             |  4 +-
 .../sanitizer_symbolizer_posix_libcdep.cpp    |  3 +-
 .../sanitizer_stacktrace_printer_test.cpp     |  9 ++++
 .../use-after-free-symbolizer-markup.cpp      | 18 +++++++
 6 files changed, 60 insertions(+), 36 deletions(-)
 create mode 100644 compiler-rt/test/asan/TestCases/Linux/use-after-free-symbolizer-markup.cpp

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
index 6a6da22c2e3e12e..25104a1da0ef799 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
@@ -12,7 +12,6 @@
 
 #include "sanitizer_common.h"
 #include "sanitizer_flags.h"
-#include "sanitizer_placement_new.h"
 #include "sanitizer_stacktrace.h"
 #include "sanitizer_stacktrace_printer.h"
 #include "sanitizer_symbolizer.h"
@@ -28,10 +27,10 @@ class StackTraceTextPrinter {
                         InternalScopedString *output,
                         InternalScopedString *dedup_token)
       : stack_trace_fmt_(stack_trace_fmt),
-        dedup_token_(dedup_token),
-        symbolize_(RenderNeedsSymbolization(stack_trace_fmt, false)),
         frame_delimiter_(frame_delimiter),
-        output_(output) {}
+        output_(output),
+        dedup_token_(dedup_token),
+        symbolize_(RenderNeedsSymbolization(stack_trace_fmt, false)){}
 
   bool ProcessAddressFrames(uptr pc) {
     SymbolizedStack *frames = symbolize_
@@ -72,20 +71,18 @@ class StackTraceTextPrinter {
   }
 
   const char *stack_trace_fmt_;
+  const char frame_delimiter_;
   int dedup_frames_ = common_flags()->dedup_token_length;
-  InternalScopedString *dedup_token_;
-  const bool symbolize_ = false;
-
- protected:
   uptr frame_num_ = 0;
-  const char frame_delimiter_;
   InternalScopedString *output_;
+  InternalScopedString *dedup_token_;
+  const bool symbolize_ = false;
 };
 
-class StackTraceMarkupPrinter : public StackTraceTextPrinter {
+class StackTraceMarkupPrinter {
  public:
   StackTraceMarkupPrinter(InternalScopedString *output)
-      : StackTraceTextPrinter("", '\n', output, nullptr){};
+      : output_(output) {}
 
   bool ProcessAddressFrames(uptr pc) {
     SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
@@ -106,11 +103,15 @@ class StackTraceMarkupPrinter : public StackTraceTextPrinter {
                   common_flags()->strip_path_prefix);
 
       if (prev_len != output_->length())
-        output_->append("%c", frame_delimiter_);
+        output_->append("%c", '\n');
     }
     frames->ClearAll();
     return true;
   }
+
+ private:
+  InternalScopedString *output_;
+  uptr frame_num_ = 0;
 };
 
 static void CopyStringToBuffer(const InternalScopedString &str, char *out_buf,
@@ -130,12 +131,11 @@ void StackTrace::PrintTo(InternalScopedString *output) const {
   CHECK(output);
 
   InternalScopedString dedup_token;
-  StackTraceTextPrinter printer =
-      common_flags()->enable_symbolizer_markup
-          ? StackTraceMarkupPrinter(output)
-          : StackTraceTextPrinter(common_flags()->stack_trace_format, '\n',
-                                  output, &dedup_token);
 
+  StackTraceMarkupPrinter markup_printer(output);
+  StackTraceTextPrinter text_printer(common_flags()->stack_trace_format, '\n',
+                                  output, &dedup_token);
+      
   if (trace == nullptr || size == 0) {
     output->append("    <empty stack>\n\n");
     return;
@@ -145,7 +145,10 @@ void StackTrace::PrintTo(InternalScopedString *output) const {
     // PCs in stack traces are actually the return addresses, that is,
     // addresses of the next instructions after the call.
     uptr pc = GetPreviousInstructionPc(trace[i]);
-    CHECK(printer.ProcessAddressFrames(pc));
+    bool result = common_flags()->enable_symbolizer_markup ?
+              markup_printer.ProcessAddressFrames(pc) :
+              text_printer.ProcessAddressFrames(pc);
+    CHECK(result);
   }
 
   // Always add a trailing empty line after stack trace.
@@ -233,12 +236,14 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
   pc = StackTrace::GetPreviousInstructionPc(pc);
 
   InternalScopedString output;
-  StackTraceTextPrinter printer =
-      common_flags()->enable_symbolizer_markup
-          ? StackTraceMarkupPrinter(&output)
-          : StackTraceTextPrinter(fmt, '\0', &output, nullptr);
-
-  if (!printer.ProcessAddressFrames(pc)) {
+  StackTraceMarkupPrinter markup_printer(&output);
+  StackTraceTextPrinter text_printer(fmt, '\0', &output, nullptr);
+                                  
+  bool result = common_flags()->enable_symbolizer_markup ?
+        markup_printer.ProcessAddressFrames(pc) :
+        text_printer.ProcessAddressFrames(pc);
+
+  if (!result) {
     output.clear();
     output.append("<can't symbolize>");
   }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
index c8473b614e7e117..f20084084ab937c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -95,8 +95,7 @@ void RenderModulesMarkup(InternalScopedString *buffer,
     }
     buffer->append("}}}\n");
 
-    const auto ranges = module.ranges();
-    for (const auto &range : ranges) {
+    for (const auto &range : module.ranges()) {
       buffer->append("{{{mmap:%p:%p:load:%d:r", range.beg,
                      range.end - range.beg, renderedModules.size());
       if (range.writable)
@@ -122,10 +121,6 @@ void RenderModulesMarkup(InternalScopedString *buffer,
   }
 }
 
-MarkupSymbolizer *MarkupSymbolizer::get(LowLevelAllocator *alloc) {
-  return new (*alloc) MarkupSymbolizer();
-}
-
 bool MarkupSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
   char buffer[kFormatFunctionMax];
   internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr);
@@ -227,7 +222,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
 
 Symbolizer *Symbolizer::PlatformInit() {
   IntrusiveList<SymbolizerTool> tools;
-  SymbolizerTool *tool = MarkupSymbolizer::get(&symbolizer_allocator_);
+  SymbolizerTool *tool = new(symbolizer_allocator_) MarkupSymbolizer();
   tools.push_back(tool);
   return new (symbolizer_allocator_) Symbolizer(tools);
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
index a09278c30bbd216..15a4493e15eae7b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
@@ -31,8 +31,6 @@ namespace __sanitizer {
 
 class MarkupSymbolizer final : public SymbolizerTool {
  public:
-  static MarkupSymbolizer *get(LowLevelAllocator *alloc);
-
   // This is used in some places for suppression checking, which we
   // don't really support for Fuchsia.  It's also used in UBSan to
   // identify a PC location to a function name, so we always fill in
@@ -66,4 +64,4 @@ void RenderFrameMarkup(InternalScopedString *, const char *, int, uptr,
 void RenderModulesMarkup(InternalScopedString *, const ListOfModules *);
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_SYMBOLIZER_MARKUP_H
\ No newline at end of file
+#endif  // SANITIZER_SYMBOLIZER_MARKUP_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index b0832b638db5228..b3712f841ba7e36 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -473,8 +473,7 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
   }
   if (common_flags()->enable_symbolizer_markup) {
     VReport(2, "Using symbolizer markup.\n");
-    SymbolizerTool *tool = MarkupSymbolizer::get(allocator);
-    list->push_back(tool);
+    list->push_back(new(*allocator) MarkupSymbolizer());
     return;
   }
   if (IsAllocatorOutOfMemory()) {
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
index 96c7571574f4c9b..5189161103ae4f7 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp
@@ -196,6 +196,15 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
   str.clear();
 
   info.Clear();
+
+  // Test for symbolizer markup
+  info.address = 0xaa00;
+  RenderFrame(&str, "", frame_no, info.address, &info,  false, true);
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "{{{bt:42:"));
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "aa00"));
+  EXPECT_NE(nullptr, internal_strstr(str.data(), "}}}"));
+  str.clear();
+  info.Clear();
 }
 
 }  // namespace __sanitizer
diff --git a/compiler-rt/test/asan/TestCases/Linux/use-after-free-symbolizer-markup.cpp b/compiler-rt/test/asan/TestCases/Linux/use-after-free-symbolizer-markup.cpp
new file mode 100644
index 000000000000000..83d65d71dc7abad
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Linux/use-after-free-symbolizer-markup.cpp
@@ -0,0 +1,18 @@
+// Test that verify that a asan produces valid symbolizer markup when enabled.
+// It does not test that asan works correctly.
+// RUN: %clangxx_asan -O1 %s -o %t 
+// RUN: env ASAN_OPTIONS=enable_symbolizer_markup=1 not %run %t 2>&1 | FileCheck %s
+// REQUIRES: linux
+
+#include <stdlib.h>
+int main() {
+  char *x = (char*)malloc(10 * sizeof(char));
+  free(x);
+  return x[5];
+}
+// COM: For element syntax see: https://llvm.org/docs/SymbolizerMarkupFormat.html
+// COM: OPEN is {{{ and CLOSE is }}}
+// CHECK: [[OPEN:{{{]]reset[[CLOSE:}}}]]
+// CHECK: [[OPEN]]module:[[MOD_ID:[0-9]+]]:{{.+}}:elf:{{[0-9a-fA-F]+}}[[CLOSE]]
+// CHECK: [[OPEN]]mmap:{{0x[0-9a-fA-F]+:0x[0-9a-fA-F]+}}:load:[[MOD_ID]]:{{r[wx]{0,2}:0x[0-9a-fA-F]+}}[[CLOSE]]
+// CHECK: [[OPEN]]bt:{{[0-9]+}}:0x{{[0-9a-fA-F]+}}[[CLOSE]]

>From 4d28dd32143ead2c75ed002e98696b3f120fa496 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andresvi at google.com>
Date: Tue, 12 Sep 2023 18:35:49 +0000
Subject: [PATCH 4/5] Remove unnecesary parameters and style changes

---
 .../sanitizer_stacktrace_printer.cpp          |  5 ++--
 .../sanitizer_symbolizer_markup.cpp           | 25 ++++++++-----------
 .../sanitizer_symbolizer_markup.h             | 11 ++++----
 3 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
index 911d4f95810e6f3..fd4e206c2958817 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
@@ -145,8 +145,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
                  bool symbolizer_markup, const char *strip_path_prefix) {
   if (symbolizer_markup) {
-    RenderFrameMarkup(buffer, format, frame_no, address, info, vs_style,
-                      strip_path_prefix);
+    RenderFrameMarkup(buffer, frame_no, address);
     return;
   }
   // info will be null in the case where symbolization is not needed for the
@@ -286,7 +285,7 @@ void RenderData(InternalScopedString *buffer, const char *format,
                 const DataInfo *DI, bool symbolizer_markup,
                 const char *strip_path_prefix) {
   if (symbolizer_markup) {
-    RenderDataMarkup(buffer, format, DI, strip_path_prefix);
+    RenderDataMarkup(buffer, DI);
     return;
   }
   for (const char *p = format; *p != '\0'; p++) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
index f20084084ab937c..c91d20184d967da 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -23,17 +23,14 @@
 
 namespace __sanitizer {
 
-void RenderDataMarkup(InternalScopedString *buffer, const char *format,
-                      const DataInfo *DI, const char *strip_path_prefix) {
+void RenderDataMarkup(InternalScopedString *buffer, const DataInfo *DI) {
   buffer->append(kFormatData, DI->start);
 }
 
-bool RenderNeedsSymbolizationMarkup(const char *format) { return false; }
+bool RenderNeedsSymbolizationMarkup() { return false; }
 
-void RenderFrameMarkup(InternalScopedString *buffer, const char *format,
-                       int frame_no, uptr address, const AddressInfo *info,
-                       bool vs_style, const char *strip_path_prefix) {
-  CHECK(!RenderNeedsSymbolizationMarkup(format));
+void RenderFrameMarkup(InternalScopedString *buffer, int frame_no, uptr address) {
+  CHECK(!RenderNeedsSymbolizationMarkup());
   buffer->append(kFormatFrame, frame_no, address);
 }
 
@@ -205,19 +202,18 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
 void RenderData(InternalScopedString *buffer, const char *format,
                 const DataInfo *DI, bool symbolizer_markup,
                 const char *strip_path_prefix) {
-  RenderDataMarkup(buffer, format, DI, strip_path_prefix);
+  RenderDataMarkup(buffer, DI);
 }
 
 bool RenderNeedsSymbolization(const char *format, bool symbolizer_markup) {
-  return RenderNeedsSymbolizationMarkup(format);
+  return RenderNeedsSymbolizationMarkup();
 }
 
 // We don't support the stack_trace_format flag at all.
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
                  uptr address, const AddressInfo *info, bool vs_style,
                  const char *strip_path_prefix) {
-  RenderFrameMarkup(buffer, format, frame_no, address, info, vs_style,
-                    strip_path_prefix);
+  RenderFrameMarkup(buffer, frame_no, address);
 }
 
 Symbolizer *Symbolizer::PlatformInit() {
@@ -234,7 +230,7 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                         UnwindSignalStackCallbackType unwind,
                         const void *unwind_context) {}
 
-#  if SANITIZER_CAN_SLOW_UNWIND
+#if SANITIZER_CAN_SLOW_UNWIND
 struct UnwindTraceArg {
   BufferedStackTrace *stack;
   u32 max_depth;
@@ -244,8 +240,7 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
   UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
   CHECK_LT(arg->stack->size, arg->max_depth);
   uptr pc = _Unwind_GetIP(ctx);
-  if (pc < PAGE_SIZE)
-    return _URC_NORMAL_STOP;
+  if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
   arg->stack->trace_buffer[arg->stack->size++] = pc;
   return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
                                              : _URC_NO_REASON);
@@ -271,7 +266,7 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
   CHECK_GE(max_depth, 2);
   UNREACHABLE("signal context doesn't exist");
 }
-#  endif  // SANITIZER_CAN_SLOW_UNWIND
+#endif  // SANITIZER_CAN_SLOW_UNWIND
 
 #endif  // SANITIZER_SYMBOLIZER_MARKUP
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
index 15a4493e15eae7b..1ad85572c8c96fa 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
@@ -52,16 +52,15 @@ class MarkupSymbolizer final : public SymbolizerTool {
 };
 
 // We ignore the format argument to __sanitizer_symbolize_global.
-void RenderDataMarkup(InternalScopedString *, const char *, const DataInfo *,
-                      const char *);
+void RenderDataMarkup(InternalScopedString *buffer, const DataInfo *DI);
 
-bool RenderNeedsSymbolizationMarkup(const char *format);
+bool RenderNeedsSymbolizationMarkup();
 
 // We don't support the stack_trace_format flag at all.
-void RenderFrameMarkup(InternalScopedString *, const char *, int, uptr,
-                       const AddressInfo *, bool, const char *);
+void RenderFrameMarkup(InternalScopedString *buffer, int frame_no, uptr address);
 
-void RenderModulesMarkup(InternalScopedString *, const ListOfModules *);
+void RenderModulesMarkup(InternalScopedString *buffer, const ListOfModules *modules);
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_SYMBOLIZER_MARKUP_H
+

>From bd9e559ef080b2ceadf96cf40a8c206ab8153387 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andresvi at google.com>
Date: Tue, 12 Sep 2023 19:25:35 +0000
Subject: [PATCH 5/5] Add style changes

---
 .../sanitizer_common/sanitizer_symbolizer_markup.cpp   | 10 ++++++----
 .../lib/sanitizer_common/sanitizer_symbolizer_markup.h |  7 ++++---
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
index c91d20184d967da..110fa8f0c74afa9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -29,7 +29,8 @@ void RenderDataMarkup(InternalScopedString *buffer, const DataInfo *DI) {
 
 bool RenderNeedsSymbolizationMarkup() { return false; }
 
-void RenderFrameMarkup(InternalScopedString *buffer, int frame_no, uptr address) {
+void RenderFrameMarkup(InternalScopedString *buffer, int frame_no,
+                       uptr address) {
   CHECK(!RenderNeedsSymbolizationMarkup());
   buffer->append(kFormatFrame, frame_no, address);
 }
@@ -230,7 +231,7 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                         UnwindSignalStackCallbackType unwind,
                         const void *unwind_context) {}
 
-#if SANITIZER_CAN_SLOW_UNWIND
+#  if SANITIZER_CAN_SLOW_UNWIND
 struct UnwindTraceArg {
   BufferedStackTrace *stack;
   u32 max_depth;
@@ -240,7 +241,8 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
   UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
   CHECK_LT(arg->stack->size, arg->max_depth);
   uptr pc = _Unwind_GetIP(ctx);
-  if (pc < PAGE_SIZE) return _URC_NORMAL_STOP;
+  if (pc < PAGE_SIZE)
+    return _URC_NORMAL_STOP;
   arg->stack->trace_buffer[arg->stack->size++] = pc;
   return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
                                              : _URC_NO_REASON);
@@ -266,7 +268,7 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
   CHECK_GE(max_depth, 2);
   UNREACHABLE("signal context doesn't exist");
 }
-#endif  // SANITIZER_CAN_SLOW_UNWIND
+#  endif  // SANITIZER_CAN_SLOW_UNWIND
 
 #endif  // SANITIZER_SYMBOLIZER_MARKUP
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
index 1ad85572c8c96fa..5b0636c45f53931 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
@@ -57,10 +57,11 @@ void RenderDataMarkup(InternalScopedString *buffer, const DataInfo *DI);
 bool RenderNeedsSymbolizationMarkup();
 
 // We don't support the stack_trace_format flag at all.
-void RenderFrameMarkup(InternalScopedString *buffer, int frame_no, uptr address);
+void RenderFrameMarkup(InternalScopedString *buffer, int frame_no,
+                       uptr address);
 
-void RenderModulesMarkup(InternalScopedString *buffer, const ListOfModules *modules);
+void RenderModulesMarkup(InternalScopedString *buffer,
+                         const ListOfModules *modules);
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_SYMBOLIZER_MARKUP_H
-



More information about the cfe-commits mailing list