Skip to content

[sanitizer_symbolizer] Add initial symbolizer markup support for linux. #73193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "sanitizer_file.h"
#include "sanitizer_flags.h"
#include "sanitizer_fuchsia.h"
#include "sanitizer_symbolizer_markup.h"

namespace __sanitizer {

Expand Down Expand Up @@ -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();
}

Expand Down
19 changes: 19 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,23 @@ void MarkupStackTracePrinter::RenderFrame(InternalScopedString *buffer,
buffer->AppendF(kFormatFrame, frame_no, address);
}

bool MarkupSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *stack) {
char buffer[kFormatFunctionMax];
internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr);
stack->info.function = internal_strdup(buffer);
return true;
}

bool MarkupSymbolizerTool::SymbolizeData(uptr addr, DataInfo *info) {
info->Clear();
info->start = addr;
return true;
}

const char *MarkupSymbolizerTool::Demangle(const char *name) {
static char buffer[kFormatDemangleMax];
internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name);
return buffer;
}

} // namespace __sanitizer
23 changes: 23 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "sanitizer_common.h"
#include "sanitizer_stacktrace_printer.h"
#include "sanitizer_symbolizer.h"
#include "sanitizer_symbolizer_internal.h"

namespace __sanitizer {

Expand All @@ -40,6 +41,28 @@ class MarkupStackTracePrinter : public StackTracePrinter {
~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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "sanitizer_platform.h"
#include "sanitizer_symbolizer_markup.h"
#if SANITIZER_POSIX
# include <dlfcn.h> // for dlsym()
# include <errno.h>
Expand Down Expand Up @@ -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)) {
Expand Down