=?utf-8?q?Andrés?= Villegas <andre...@google.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/73...@github.com>
https://github.com/avillega updated https://github.com/llvm/llvm-project/pull/73194 >From 31c40ba8aea7192c8481a3ab046d9e756231e986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andre...@google.com> Date: Thu, 23 Nov 2023 02:14:42 +0000 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 [skip ci] --- .../lib/sanitizer_common/CMakeLists.txt | 2 + .../lib/sanitizer_common/sanitizer_flags.inc | 4 + .../sanitizer_stacktrace_printer.cpp | 4 + .../sanitizer_symbolizer_markup.cpp | 111 ++++++------------ .../sanitizer_symbolizer_markup.h | 68 +++++++++++ .../sanitizer_symbolizer_markup_fuchsia.cpp | 83 +++++++++++++ .../sanitizer_symbolizer_posix_libcdep.cpp | 7 ++ 7 files changed, 201 insertions(+), 78 deletions(-) create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup_fuchsia.cpp diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index 61e832a30eb3767..fb7584c298a1c94 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -88,6 +88,7 @@ set(SANITIZER_SYMBOLIZER_SOURCES sanitizer_symbolizer_libcdep.cpp sanitizer_symbolizer_mac.cpp sanitizer_symbolizer_markup.cpp + sanitizer_symbolizer_markup_fuchsia.cpp sanitizer_symbolizer_posix_libcdep.cpp sanitizer_symbolizer_report.cpp sanitizer_symbolizer_report_fuchsia.cpp @@ -195,6 +196,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 949bdbd148b6b89..7d0c7c4b63c9162 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -275,3 +275,7 @@ COMMON_FLAG(bool, test_only_emulate_no_memorymap, false, // program. COMMON_FLAG(bool, test_only_replace_dlopen_main_program, false, "TEST ONLY replace dlopen(<main program>,...) with dlopen(NULL)") + +COMMON_FLAG(bool, enable_symbolizer_markup, SANITIZER_FUCHSIA, + "Use sanitizer symbolizer markup, available on Linux " + "and always set true for fuchsia.") diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp index 88f186b9c20c105..748d832ccc211d0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp @@ -16,6 +16,7 @@ #include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_fuchsia.h" +#include "sanitizer_symbolizer_markup.h" namespace __sanitizer { @@ -62,6 +63,9 @@ const char *StackTracePrinter::StripFunctionName(const char *function) { #if !SANITIZER_SYMBOLIZER_MARKUP StackTracePrinter *StackTracePrinter::NewStackTracePrinter() { + if (common_flags()->enable_symbolizer_markup) + return new (GetGlobalLowLevelAllocator()) MarkupStackTracePrinter(); + return new (GetGlobalLowLevelAllocator()) FormattedStackTracePrinter(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp index c7332af7d9efd5a..1627908185f2009 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp @@ -8,105 +8,60 @@ // // This file is shared between various sanitizers' runtime libraries. // -// Implementation of offline markup symbolizer. +// 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. +// See the spec at: +// https://llvm.org/docs/SymbolizerMarkupFormat.html //===----------------------------------------------------------------------===// -#include "sanitizer_platform.h" +#include "sanitizer_symbolizer_markup.h" -#if SANITIZER_SYMBOLIZER_MARKUP - -# include "sanitizer_common.h" -# include "sanitizer_stacktrace_printer.h" -# include "sanitizer_symbolizer.h" -# include "sanitizer_symbolizer_markup_constants.h" +#include "sanitizer_common.h" +#include "sanitizer_stacktrace_printer.h" +#include "sanitizer_symbolizer.h" +#include "sanitizer_symbolizer_markup_constants.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 - -// 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; +void MarkupStackTracePrinter::RenderData(InternalScopedString *buffer, + const char *format, const DataInfo *DI, + const char *strip_path_prefix) { + buffer->AppendF(kFormatData, DI->start); } -// This is used mostly for suppression matching. Making it work -// would enable "interceptor_via_lib" suppressions. It's also used -// once in UBSan to say "in module ..." in a message that also -// includes an address in the module, so post-processing can already -// pretty-print that so as to indicate the module. -bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, - uptr *module_address) { +bool MarkupStackTracePrinter::RenderNeedsSymbolization(const char *format) { return false; } -// This is mainly used by hwasan for online symbolization. This isn't needed -// since hwasan can always just dump stack frames for offline symbolization. -bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { return false; } +// We don't support the stack_trace_format flag at all. +void MarkupStackTracePrinter::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->AppendF(kFormatFrame, frame_no, address); +} -// 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. -SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { - SymbolizedStack *s = SymbolizedStack::New(addr); +bool MarkupSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *stack) { char buffer[kFormatFunctionMax]; internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr); - s->info.function = internal_strdup(buffer); - return s; + stack->info.function = internal_strdup(buffer); + return true; } -// Always claim we succeeded, so that RenderDataInfo will be called. -bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { +bool MarkupSymbolizerTool::SymbolizeData(uptr addr, DataInfo *info) { info->Clear(); info->start = addr; return true; } -class MarkupStackTracePrinter : public StackTracePrinter { - // We ignore the format argument to __sanitizer_symbolize_global. - void RenderData(InternalScopedString *buffer, const char *format, - const DataInfo *DI, const char *strip_path_prefix) override { - buffer->AppendF(kFormatData, DI->start); - } - - bool RenderNeedsSymbolization(const char *format) override { return false; } - - // 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) override { - CHECK(!RenderNeedsSymbolization(format)); - buffer->AppendF(kFormatFrame, frame_no, address); - } - - protected: - ~MarkupStackTracePrinter(); -}; - -StackTracePrinter *StackTracePrinter::NewStackTracePrinter() { - return new (GetGlobalLowLevelAllocator()) MarkupStackTracePrinter(); -} - -Symbolizer *Symbolizer::PlatformInit() { - return new (symbolizer_allocator_) Symbolizer({}); +const char *MarkupSymbolizerTool::Demangle(const char *name) { + static char buffer[kFormatDemangleMax]; + internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name); + return buffer; } -void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); } - } // namespace __sanitizer - -#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 new file mode 100644 index 000000000000000..07630d0b3bdf417 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h @@ -0,0 +1,68 @@ +//===-- 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. +// +// Header for the offline markup symbolizer. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_SYMBOLIZER_MARKUP_H +#define SANITIZER_SYMBOLIZER_MARKUP_H + +#include "sanitizer_common.h" +#include "sanitizer_stacktrace_printer.h" +#include "sanitizer_symbolizer.h" +#include "sanitizer_symbolizer_internal.h" + +namespace __sanitizer { + +class MarkupStackTracePrinter : public StackTracePrinter { + public: + // 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 = "") override; + + bool RenderNeedsSymbolization(const char *format) override; + + // We ignore the format argument to __sanitizer_symbolize_global. + void RenderData(InternalScopedString *buffer, const char *format, + const DataInfo *DI, + const char *strip_path_prefix = "") override; + + private: + void RenderContext(InternalScopedString *buffer); + + protected: + ~MarkupStackTracePrinter() {} +}; + +class MarkupSymbolizerTool final : public SymbolizerTool { + public: + // 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; +}; + +} // namespace __sanitizer + +#endif // SANITIZER_SYMBOLIZER_MARKUP_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup_fuchsia.cpp new file mode 100644 index 000000000000000..f6c49aa59d7b559 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup_fuchsia.cpp @@ -0,0 +1,83 @@ +//===-- sanitizer_symbolizer_markup_fuchsia.cpp ---------------------------===// +// +// 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. +// +// Fuchsia specific implementation of offline markup symbolizer. +//===----------------------------------------------------------------------===// +#include "sanitizer_platform.h" + +#if SANITIZER_SYMBOLIZER_MARKUP + +# include "sanitizer_common.h" +# include "sanitizer_stacktrace_printer.h" +# include "sanitizer_symbolizer.h" +# include "sanitizer_symbolizer_markup.h" +# include "sanitizer_symbolizer_markup_constants.h" + +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; +} + +// This is used mostly for suppression matching. Making it work +// would enable "interceptor_via_lib" suppressions. It's also used +// once in UBSan to say "in module ..." in a message that also +// includes an address in the module, so post-processing can already +// pretty-print that so as to indicate the module. +bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, + uptr *module_address) { + return false; +} + +// This is mainly used by hwasan for online symbolization. This isn't needed +// since hwasan can always just dump stack frames for offline symbolization. +bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { return false; } + +// 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. +SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { + SymbolizedStack *s = SymbolizedStack::New(addr); + char buffer[kFormatFunctionMax]; + internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr); + s->info.function = internal_strdup(buffer); + 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; +} + +// Fuchsia only uses MarkupStackTracePrinter +StackTracePrinter *StackTracePrinter::NewStackTracePrinter() { + return new (GetGlobalLowLevelAllocator()) MarkupStackTracePrinter(); +} + +Symbolizer *Symbolizer::PlatformInit() { + return new (symbolizer_allocator_) Symbolizer({}); +} + +void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); } + +} // namespace __sanitizer + +#endif // SANITIZER_SYMBOLIZER_MARKUP 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 d92349c04fffabd..28f11352a6b5bbe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" +#include "sanitizer_symbolizer_markup.h" #if SANITIZER_POSIX # include <dlfcn.h> // for dlsym() # include <errno.h> @@ -475,6 +476,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"); + SymbolizerTool *tool = new (*allocator) MarkupSymbolizerTool(); + CHECK(tool); + list->push_back(tool); + } if (IsAllocatorOutOfMemory()) { VReport(2, "Cannot use internal symbolizer: out of memory\n"); } else if (SymbolizerTool *tool = InternalSymbolizer::get(allocator)) { >From a03c81be070eccb0e064af314d02216e76bab854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Villegas?= <andre...@google.com> Date: Tue, 28 Nov 2023 21:17:10 +0000 Subject: [PATCH 2/2] Fix review comments and squash tests Created using spr 1.3.4 --- .../sanitizer_symbolizer_markup.cpp | 34 +++++------------ .../sanitizer_symbolizer_markup.h | 11 ++++++ .../TestCases/print-stack-trace-markup.cpp | 38 +++++++++++++++++++ 3 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 compiler-rt/test/sanitizer_common/TestCases/print-stack-trace-markup.cpp diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp index fe9933e942eba55..cbd111e975781a3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp @@ -19,7 +19,6 @@ #include "sanitizer_symbolizer_markup.h" #include "sanitizer_common.h" -#include "sanitizer_stacktrace_printer.h" #include "sanitizer_symbolizer.h" #include "sanitizer_symbolizer_markup_constants.h" @@ -73,13 +72,6 @@ const char *MarkupSymbolizerTool::Demangle(const char *name) { // symbolization and pretty-print the markup. #if !SANITIZER_FUCHSIA -// Simplier view of a LoadedModule. It only holds information necessary to -// identify unique modules. -struct RenderedModule { - char *full_name; - uptr base_address; - u8 uuid[kModuleUUIDSize]; // BuildId -}; static bool ModulesEq(const LoadedModule &module, const RenderedModule &renderedModule) { @@ -136,39 +128,31 @@ static void RenderMmaps(InternalScopedString *buffer, } void MarkupStackTracePrinter::RenderContext(InternalScopedString *buffer) { - // Keeps track of the modules that have been rendered. - static bool initialized = false; - static InternalMmapVectorNoCtor<RenderedModule> renderedModules; - if (!initialized) { - // arbitrary initial size, counting the main module plus some important libs - // like libc. - renderedModules.Initialize(3); - initialized = true; - } - - if (renderedModules.size() == 0) + if (renderedModules_.size() == 0) buffer->Append("{{{reset}}}\n"); const auto &modules = Symbolizer::GetOrInit()->GetRefreshedListOfModules(); for (const auto &module : modules) { - if (ModuleHasBeenRendered(module, renderedModules)) + if (ModuleHasBeenRendered(module, renderedModules_)) continue; // symbolizer markup id, used to refer to this modules from other contextual // elements - uptr moduleId = renderedModules.size(); + uptr moduleId = renderedModules_.size(); RenderModule(buffer, module, moduleId); RenderMmaps(buffer, module, moduleId); - RenderedModule renderedModule{ - internal_strdup(module.full_name()), module.base_address(), {}}; + renderedModules_.push_back({ + internal_strdup(module.full_name()), + module.base_address(), + {}, + }); // kModuleUUIDSize is the size of curModule.uuid CHECK_GE(kModuleUUIDSize, module.uuid_size()); - internal_memcpy(renderedModule.uuid, module.uuid(), module.uuid_size()); - renderedModules.push_back(renderedModule); + internal_memcpy(renderedModules_.back().uuid, module.uuid(), module.uuid_size()); } } #endif // !SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h index 07630d0b3bdf417..bc2ab24d625bb5a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h @@ -20,6 +20,14 @@ namespace __sanitizer { +// Simplier view of a LoadedModule. It only holds information necessary to +// identify unique modules. +struct RenderedModule { + char *full_name; + uptr base_address; + u8 uuid[kModuleUUIDSize]; // BuildId +}; + class MarkupStackTracePrinter : public StackTracePrinter { public: // We don't support the stack_trace_format flag at all. @@ -35,6 +43,9 @@ class MarkupStackTracePrinter : public StackTracePrinter { const char *strip_path_prefix = "") override; private: + // Keeps track of the modules that have been rendered to avoid re-rendering + // them + InternalMmapVector<RenderedModule> renderedModules_; void RenderContext(InternalScopedString *buffer); protected: diff --git a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace-markup.cpp b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace-markup.cpp new file mode 100644 index 000000000000000..15d89d091a99e33 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace-markup.cpp @@ -0,0 +1,38 @@ +// RUN: %clangxx %s -o %t +// RUN: %env_tool_opts=enable_symbolizer_markup=1 %run %t 2>&1 | FileCheck %s + +// REQUIRES: linux +#include <sanitizer/common_interface_defs.h> + +void Bar() { __sanitizer_print_stack_trace(); } + +void Foo() { + Bar(); + return; +} + +void Baz() { __sanitizer_print_stack_trace(); } + +int main() { + Foo(); + Baz(); + return 0; +} + +// 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:0x{{[0-9a-fA-F]+}}[[CLOSE]] +// CHECK-NEXT: [[OPEN]]bt:1:0x{{[0-9a-fA-F]+}}[[CLOSE]] +// CHECK-NEXT: [[OPEN]]bt:2:0x{{[0-9a-fA-F]+}}[[CLOSE]] + +// COM: Emitting a second backtrace should not emit contextual elements in this case. +// CHECK-NOT: [[OPEN:{{{]]reset[[CLOSE:}}}]] +// CHECK-NOT: [[OPEN]]module:[[MOD_ID:[0-9]+]]:{{.+}}:elf:{{[0-9a-fA-F]+}}[[CLOSE]] +// CHECK-NOT: [[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:0x{{[0-9a-fA-F]+}}[[CLOSE]] +// CHECK-NEXT: [[OPEN]]bt:1:0x{{[0-9a-fA-F]+}}[[CLOSE]] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits