annotate libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 //===-- sanitizer_stacktrace_libcdep.cpp ----------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 // This file is shared between AddressSanitizer and ThreadSanitizer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 // run-time libraries.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 #include "sanitizer_common.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "sanitizer_placement_new.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "sanitizer_stacktrace.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "sanitizer_stacktrace_printer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "sanitizer_symbolizer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 namespace __sanitizer {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 void StackTrace::Print() const {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 if (trace == nullptr || size == 0) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 Printf(" <empty stack>\n\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 InternalScopedString frame_desc(GetPageSizeCached() * 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 InternalScopedString dedup_token(GetPageSizeCached());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 int dedup_frames = common_flags()->dedup_token_length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 uptr frame_num = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 for (uptr i = 0; i < size && trace[i]; i++) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 // PCs in stack traces are actually the return addresses, that is,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 // addresses of the next instructions after the call.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 uptr pc = GetPreviousInstructionPc(trace[i]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 CHECK(frames);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 frame_desc.clear();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 cur->info, common_flags()->symbolize_vs_style,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 common_flags()->strip_path_prefix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 Printf("%s\n", frame_desc.data());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 if (dedup_frames-- > 0) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 if (dedup_token.length())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 dedup_token.append("--");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 if (cur->info.function != nullptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 dedup_token.append(cur->info.function);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 frames->ClearAll();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 // Always print a trailing empty line after stack trace.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 Printf("\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 if (dedup_token.length())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 Printf("DEDUP_TOKEN: %s\n", dedup_token.data());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 uptr stack_top, uptr stack_bottom,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 bool request_fast_unwind) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 // Ensures all call sites get what they requested.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 CHECK_EQ(request_fast_unwind, WillUseFastUnwind(request_fast_unwind));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 top_frame_bp = (max_depth > 0) ? bp : 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 // Avoid doing any work for small max_depth.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 if (max_depth == 0) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 size = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 if (max_depth == 1) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 size = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 trace_buffer[0] = pc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 if (!WillUseFastUnwind(request_fast_unwind)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 #if SANITIZER_CAN_SLOW_UNWIND
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 if (context)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 UnwindSlow(pc, context, max_depth);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 UnwindSlow(pc, max_depth);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 #else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 UNREACHABLE("slow unwind requested but not available");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 } else {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 UnwindFast(pc, bp, stack_top, stack_bottom, max_depth);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 static int GetModuleAndOffsetForPc(uptr pc, char *module_name,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 uptr module_name_len, uptr *pc_offset) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 const char *found_module_name = nullptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 bool ok = Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC(
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 pc, &found_module_name, pc_offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 if (!ok) return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 if (module_name && module_name_len) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 internal_strncpy(module_name, found_module_name, module_name_len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 module_name[module_name_len - 1] = '\x00';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 } // namespace __sanitizer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 using namespace __sanitizer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 extern "C" {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 SANITIZER_INTERFACE_ATTRIBUTE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 uptr out_buf_size) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 if (!out_buf_size) return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 pc = StackTrace::GetPreviousInstructionPc(pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 if (!frame) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 internal_strncpy(out_buf, "<can't symbolize>", out_buf_size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 out_buf[out_buf_size - 1] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 InternalScopedString frame_desc(GetPageSizeCached());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 uptr frame_num = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 // Reserve one byte for the final 0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 char *out_end = out_buf + out_buf_size - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 for (SymbolizedStack *cur = frame; cur && out_buf < out_end;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 cur = cur->next) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 frame_desc.clear();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 RenderFrame(&frame_desc, fmt, frame_num++, cur->info,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 common_flags()->symbolize_vs_style,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 common_flags()->strip_path_prefix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 if (!frame_desc.length())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 // Reserve one byte for the terminating 0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 uptr n = out_end - out_buf - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 internal_strncpy(out_buf, frame_desc.data(), n);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 out_buf += __sanitizer::Min<uptr>(n, frame_desc.length());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 *out_buf++ = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 CHECK(out_buf <= out_end);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 *out_buf = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 SANITIZER_INTERFACE_ATTRIBUTE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 void __sanitizer_symbolize_global(uptr data_addr, const char *fmt,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 char *out_buf, uptr out_buf_size) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 if (!out_buf_size) return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 out_buf[0] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 DataInfo DI;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 if (!Symbolizer::GetOrInit()->SymbolizeData(data_addr, &DI)) return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 InternalScopedString data_desc(GetPageSizeCached());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 RenderData(&data_desc, fmt, &DI, common_flags()->strip_path_prefix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 internal_strncpy(out_buf, data_desc.data(), out_buf_size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 out_buf[out_buf_size - 1] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 SANITIZER_INTERFACE_ATTRIBUTE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 int __sanitizer_get_module_and_offset_for_pc(uptr pc, char *module_name,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 uptr module_name_len,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 uptr *pc_offset) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 return __sanitizer::GetModuleAndOffsetForPc(pc, module_name, module_name_len,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 pc_offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 } // extern "C"