1 //===-- sanitizer_common.cc -----------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between sanitizers' run-time libraries.
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_stacktrace_printer.h"
13 #include "sanitizer_file.h"
14 #include "sanitizer_fuchsia.h"
16 namespace __sanitizer
{
18 // sanitizer_symbolizer_fuchsia.cc implements these differently for Fuchsia.
19 #if !SANITIZER_FUCHSIA
21 static const char *StripFunctionName(const char *function
, const char *prefix
) {
22 if (!function
) return nullptr;
23 if (!prefix
) return function
;
24 uptr prefix_len
= internal_strlen(prefix
);
25 if (0 == internal_strncmp(function
, prefix
, prefix_len
))
26 return function
+ prefix_len
;
30 static const char kDefaultFormat
[] = " #%n %p %F %L";
32 void RenderFrame(InternalScopedString
*buffer
, const char *format
, int frame_no
,
33 const AddressInfo
&info
, bool vs_style
,
34 const char *strip_path_prefix
, const char *strip_func_prefix
) {
35 if (0 == internal_strcmp(format
, "DEFAULT"))
36 format
= kDefaultFormat
;
37 for (const char *p
= format
; *p
!= '\0'; p
++) {
39 buffer
->append("%c", *p
);
47 // Frame number and all fields of AddressInfo structure.
49 buffer
->append("%zu", frame_no
);
52 buffer
->append("0x%zx", info
.address
);
55 buffer
->append("%s", StripPathPrefix(info
.module
, strip_path_prefix
));
58 buffer
->append("0x%zx", info
.module_offset
);
61 buffer
->append("%s", StripFunctionName(info
.function
, strip_func_prefix
));
64 buffer
->append("0x%zx", info
.function_offset
!= AddressInfo::kUnknown
65 ? info
.function_offset
69 buffer
->append("%s", StripPathPrefix(info
.file
, strip_path_prefix
));
72 buffer
->append("%d", info
.line
);
75 buffer
->append("%d", info
.column
);
77 // Smarter special cases.
79 // Function name and offset, if file is unknown.
81 buffer
->append("in %s",
82 StripFunctionName(info
.function
, strip_func_prefix
));
83 if (!info
.file
&& info
.function_offset
!= AddressInfo::kUnknown
)
84 buffer
->append("+0x%zx", info
.function_offset
);
88 // File/line information.
89 RenderSourceLocation(buffer
, info
.file
, info
.line
, info
.column
, vs_style
,
93 // Source location, or module location.
95 RenderSourceLocation(buffer
, info
.file
, info
.line
, info
.column
,
96 vs_style
, strip_path_prefix
);
97 } else if (info
.module
) {
98 RenderModuleLocation(buffer
, info
.module
, info
.module_offset
,
99 info
.module_arch
, strip_path_prefix
);
101 buffer
->append("(<unknown module>)");
105 // Module basename and offset, or PC.
106 if (info
.address
& kExternalPCBit
)
107 {} // There PCs are not meaningful.
108 else if (info
.module
)
109 // Always strip the module name for %M.
110 RenderModuleLocation(buffer
, StripModuleName(info
.module
),
111 info
.module_offset
, info
.module_arch
, "");
113 buffer
->append("(%p)", (void *)info
.address
);
116 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p
,
123 void RenderData(InternalScopedString
*buffer
, const char *format
,
124 const DataInfo
*DI
, const char *strip_path_prefix
) {
125 for (const char *p
= format
; *p
!= '\0'; p
++) {
127 buffer
->append("%c", *p
);
133 buffer
->append("%%");
136 buffer
->append("%s", StripPathPrefix(DI
->file
, strip_path_prefix
));
139 buffer
->append("%d", DI
->line
);
142 buffer
->append("%s", DI
->name
);
145 Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p
,
152 #endif // !SANITIZER_FUCHSIA
154 void RenderSourceLocation(InternalScopedString
*buffer
, const char *file
,
155 int line
, int column
, bool vs_style
,
156 const char *strip_path_prefix
) {
157 if (vs_style
&& line
> 0) {
158 buffer
->append("%s(%d", StripPathPrefix(file
, strip_path_prefix
), line
);
160 buffer
->append(",%d", column
);
165 buffer
->append("%s", StripPathPrefix(file
, strip_path_prefix
));
167 buffer
->append(":%d", line
);
169 buffer
->append(":%d", column
);
173 void RenderModuleLocation(InternalScopedString
*buffer
, const char *module
,
174 uptr offset
, ModuleArch arch
,
175 const char *strip_path_prefix
) {
176 buffer
->append("(%s", StripPathPrefix(module
, strip_path_prefix
));
177 if (arch
!= kModuleArchUnknown
) {
178 buffer
->append(":%s", ModuleArchToString(arch
));
180 buffer
->append("+0x%zx)", offset
);
183 } // namespace __sanitizer