1 //===-- sanitizer_common.cc -----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between sanitizers' run-time libraries.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_stacktrace_printer.h"
16 namespace __sanitizer {
18 static const char *StripFunctionName(const char *function, const char *prefix) {
19 if (!function) return nullptr;
20 if (!prefix) return function;
21 uptr prefix_len = internal_strlen(prefix);
22 if (0 == internal_strncmp(function, prefix, prefix_len))
23 return function + prefix_len;
27 static const char kDefaultFormat[] = " #%n %p %F %L";
29 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
30 const AddressInfo &info, bool vs_style,
31 const char *strip_path_prefix, const char *strip_func_prefix) {
32 if (0 == internal_strcmp(format, "DEFAULT"))
33 format = kDefaultFormat;
34 for (const char *p = format; *p != '\0'; p++) {
36 buffer->append("%c", *p);
44 // Frame number and all fields of AddressInfo structure.
46 buffer->append("%zu", frame_no);
49 buffer->append("0x%zx", info.address);
52 buffer->append("%s", StripPathPrefix(info.module, strip_path_prefix));
55 buffer->append("0x%zx", info.module_offset);
58 buffer->append("%s", StripFunctionName(info.function, strip_func_prefix));
61 buffer->append("0x%zx", info.function_offset != AddressInfo::kUnknown
62 ? info.function_offset
66 buffer->append("%s", StripPathPrefix(info.file, strip_path_prefix));
69 buffer->append("%d", info.line);
72 buffer->append("%d", info.column);
74 // Smarter special cases.
76 // Function name and offset, if file is unknown.
78 buffer->append("in %s",
79 StripFunctionName(info.function, strip_func_prefix));
80 if (!info.file && info.function_offset != AddressInfo::kUnknown)
81 buffer->append("+0x%zx", info.function_offset);
85 // File/line information.
86 RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,
90 // Source location, or module location.
92 RenderSourceLocation(buffer, info.file, info.line, info.column,
93 vs_style, strip_path_prefix);
94 } else if (info.module) {
95 RenderModuleLocation(buffer, info.module, info.module_offset,
98 buffer->append("(<unknown module>)");
102 // Module basename and offset, or PC.
103 if (info.address & kExternalPCBit)
104 {} // There PCs are not meaningful.
105 else if (info.module)
106 buffer->append("(%s+%p)", StripModuleName(info.module),
107 (void *)info.module_offset);
109 buffer->append("(%p)", (void *)info.address);
112 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
119 void RenderData(InternalScopedString *buffer, const char *format,
120 const DataInfo *DI, const char *strip_path_prefix) {
121 for (const char *p = format; *p != '\0'; p++) {
123 buffer->append("%c", *p);
129 buffer->append("%%");
132 buffer->append("%s", StripPathPrefix(DI->file, strip_path_prefix));
135 buffer->append("%d", DI->line);
138 buffer->append("%s", DI->name);
141 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
148 void RenderSourceLocation(InternalScopedString *buffer, const char *file,
149 int line, int column, bool vs_style,
150 const char *strip_path_prefix) {
151 if (vs_style && line > 0) {
152 buffer->append("%s(%d", StripPathPrefix(file, strip_path_prefix), line);
154 buffer->append(",%d", column);
159 buffer->append("%s", StripPathPrefix(file, strip_path_prefix));
161 buffer->append(":%d", line);
163 buffer->append(":%d", column);
167 void RenderModuleLocation(InternalScopedString *buffer, const char *module,
168 uptr offset, const char *strip_path_prefix) {
169 buffer->append("(%s+0x%zx)", StripPathPrefix(module, strip_path_prefix),
173 } // namespace __sanitizer