Skip to content

Commit a0884da

Browse files
committed
[NFC][Sanitizer] Pull up GetStackTrace into sanitizer_common
We already independently declare GetStackTrace in all (except TSan) sanitizer runtime headers. Lets move it to sanitizer_stacktrace.h to have one canonical way to fill in a BufferedStackFrame. Also enables us to use it in sanitizer_common itself. This patch defines GetStackTrace for TSan and moves the function from ubsan_diag.cc to ubsan_diag_standalone.cc to avoid duplicate symbols for the UBSan-ASan runtime. Other than that this patch just moves the code out of headers and into the correct namespace. Reviewers: vitalybuka Differential Revision: https://reviews.llvm.org/D58651 llvm-svn: 355039
1 parent 6a19836 commit a0884da

File tree

13 files changed

+114
-108
lines changed

13 files changed

+114
-108
lines changed

compiler-rt/lib/asan/asan_stack.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,34 @@ u32 GetMallocContextSize() {
2828

2929
} // namespace __asan
3030

31+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
32+
uptr pc, uptr bp, void *context, bool fast) {
33+
using namespace __asan;
34+
#if SANITIZER_WINDOWS
35+
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
36+
#else
37+
AsanThread *t;
38+
stack->size = 0;
39+
if (LIKELY(asan_inited)) {
40+
if ((t = GetCurrentThread()) && !t->isUnwinding()) {
41+
uptr stack_top = t->stack_top();
42+
uptr stack_bottom = t->stack_bottom();
43+
ScopedUnwinding unwind_scope(t);
44+
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
45+
if (StackTrace::WillUseFastUnwind(fast))
46+
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom,
47+
true);
48+
else
49+
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
50+
}
51+
} else if (!t && !fast) {
52+
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
53+
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
54+
}
55+
}
56+
#endif // SANITIZER_WINDOWS
57+
}
58+
3159
// ------------------ Interface -------------- {{{1
3260

3361
extern "C" {

compiler-rt/lib/asan/asan_stack.h

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,6 @@ static const u32 kDefaultMallocContextSize = 30;
2626
void SetMallocContextSize(u32 size);
2727
u32 GetMallocContextSize();
2828

29-
// Get the stack trace with the given pc and bp.
30-
// The pc will be in the position 0 of the resulting stack trace.
31-
// The bp may refer to the current frame or to the caller's frame.
32-
ALWAYS_INLINE
33-
void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
34-
void *context, bool fast) {
35-
#if SANITIZER_WINDOWS
36-
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
37-
#else
38-
AsanThread *t;
39-
stack->size = 0;
40-
if (LIKELY(asan_inited)) {
41-
if ((t = GetCurrentThread()) && !t->isUnwinding()) {
42-
uptr stack_top = t->stack_top();
43-
uptr stack_bottom = t->stack_bottom();
44-
ScopedUnwinding unwind_scope(t);
45-
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
46-
if (StackTrace::WillUseFastUnwind(fast))
47-
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom,
48-
true);
49-
else
50-
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
51-
}
52-
} else if (!t && !fast) {
53-
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
54-
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
55-
}
56-
}
57-
#endif // SANITIZER_WINDOWS
58-
}
59-
6029
} // namespace __asan
6130

6231
// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors

compiler-rt/lib/hwasan/hwasan.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,26 +144,6 @@ static void InitializeFlags() {
144144
if (common_flags()->help) parser.PrintFlagDescriptions();
145145
}
146146

147-
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
148-
void *context, bool request_fast_unwind) {
149-
Thread *t = GetCurrentThread();
150-
if (!t) {
151-
// the thread is still being created.
152-
stack->size = 0;
153-
return;
154-
}
155-
if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
156-
// Block reports from our interceptors during _Unwind_Backtrace.
157-
SymbolizerScope sym_scope;
158-
return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
159-
}
160-
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
161-
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
162-
true);
163-
else
164-
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
165-
}
166-
167147
static void HWAsanCheckFailed(const char *file, int line, const char *cond,
168148
u64 v1, u64 v2) {
169149
Report("HWAddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
@@ -264,6 +244,28 @@ void InitInstrumentation() {
264244

265245
} // namespace __hwasan
266246

247+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
248+
uptr bp, void *context,
249+
bool request_fast_unwind) {
250+
using namespace __hwasan;
251+
Thread *t = GetCurrentThread();
252+
if (!t) {
253+
// the thread is still being created.
254+
stack->size = 0;
255+
return;
256+
}
257+
if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
258+
// Block reports from our interceptors during _Unwind_Backtrace.
259+
SymbolizerScope sym_scope;
260+
return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
261+
}
262+
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
263+
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
264+
true);
265+
else
266+
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
267+
}
268+
267269
// Interface.
268270

269271
using namespace __hwasan;

compiler-rt/lib/hwasan/hwasan.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ struct SymbolizerScope {
104104
~SymbolizerScope() { ExitSymbolizer(); }
105105
};
106106

107-
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
108-
void *context, bool request_fast_unwind);
109-
110107
// Returns a "chained" origin id, pointing to the given stack trace followed by
111108
// the previous origin id.
112109
u32 ChainOrigin(u32 id, StackTrace *stack);

compiler-rt/lib/lsan/lsan.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ bool WordIsPoisoned(uptr addr) {
3232

3333
} // namespace __lsan
3434

35+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
36+
uptr pc, uptr bp, void *context, bool fast) {
37+
using namespace __lsan;
38+
uptr stack_top = 0, stack_bottom = 0;
39+
ThreadContext *t;
40+
if (StackTrace::WillUseFastUnwind(fast) &&
41+
(t = CurrentThreadContext())) {
42+
stack_top = t->stack_end();
43+
stack_bottom = t->stack_begin();
44+
}
45+
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
46+
if (StackTrace::WillUseFastUnwind(fast))
47+
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
48+
else
49+
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
50+
}
51+
}
52+
3553
using namespace __lsan; // NOLINT
3654

3755
static void InitializeFlags() {

compiler-rt/lib/lsan/lsan.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,6 @@ void ReplaceSystemMalloc();
4040
__lsan_init(); \
4141
} while (0)
4242

43-
// Get the stack trace with the given pc and bp.
44-
// The pc will be in the position 0 of the resulting stack trace.
45-
// The bp may refer to the current frame or to the caller's frame.
46-
ALWAYS_INLINE
47-
void GetStackTrace(__sanitizer::BufferedStackTrace *stack,
48-
__sanitizer::uptr max_depth, __sanitizer::uptr pc,
49-
__sanitizer::uptr bp, void *context, bool fast) {
50-
uptr stack_top = 0, stack_bottom = 0;
51-
ThreadContext *t;
52-
if (__sanitizer::StackTrace::WillUseFastUnwind(fast) &&
53-
(t = CurrentThreadContext())) {
54-
stack_top = t->stack_end();
55-
stack_bottom = t->stack_begin();
56-
}
57-
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
58-
if (StackTrace::WillUseFastUnwind(fast))
59-
stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
60-
else
61-
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
62-
}
63-
}
64-
6543
} // namespace __lsan
6644

6745
extern bool lsan_inited;

compiler-rt/lib/msan/msan.cc

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -221,21 +221,6 @@ static void InitializeFlags() {
221221
if (f->store_context_size < 1) f->store_context_size = 1;
222222
}
223223

224-
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
225-
void *context, bool request_fast_unwind) {
226-
MsanThread *t = GetCurrentThread();
227-
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
228-
// Block reports from our interceptors during _Unwind_Backtrace.
229-
SymbolizerScope sym_scope;
230-
return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
231-
}
232-
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
233-
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
234-
true);
235-
else
236-
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
237-
}
238-
239224
void PrintWarning(uptr pc, uptr bp) {
240225
PrintWarningWithOrigin(pc, bp, __msan_origin_tls);
241226
}
@@ -316,6 +301,23 @@ u32 ChainOrigin(u32 id, StackTrace *stack) {
316301

317302
} // namespace __msan
318303

304+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
305+
uptr bp, void *context,
306+
bool request_fast_unwind) {
307+
using namespace __msan;
308+
MsanThread *t = GetCurrentThread();
309+
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
310+
// Block reports from our interceptors during _Unwind_Backtrace.
311+
SymbolizerScope sym_scope;
312+
return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
313+
}
314+
if (StackTrace::WillUseFastUnwind(request_fast_unwind))
315+
stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
316+
true);
317+
else
318+
stack->Unwind(max_s, pc, 0, context, 0, 0, false);
319+
}
320+
319321
// Interface.
320322

321323
using namespace __msan;

compiler-rt/lib/msan/msan.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,6 @@ struct SymbolizerScope {
312312
void PrintWarning(uptr pc, uptr bp);
313313
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
314314

315-
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
316-
void *context, bool request_fast_unwind);
317-
318315
// Unpoison first n function arguments.
319316
void UnpoisonParam(uptr n);
320317
void UnpoisonThreadLocalState();

compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {
121121
return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);
122122
}
123123

124+
// Get the stack trace with the given pc and bp.
125+
// The pc will be in the position 0 of the resulting stack trace.
126+
// The bp may refer to the current frame or to the caller's frame.
127+
void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
128+
void *context, bool request_fast_unwind);
129+
124130
} // namespace __sanitizer
125131

126132
// Use this macro if you want to print stack trace with the caller

compiler-rt/lib/tsan/rtl/tsan_stack_trace.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,15 @@ void VarSizeStackTrace::ReverseOrder() {
4848
}
4949

5050
} // namespace __tsan
51+
52+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
53+
uptr pc, uptr bp, void *context,
54+
bool request_fast_unwind) {
55+
uptr top = 0;
56+
uptr bottom = 0;
57+
if (StackTrace::WillUseFastUnwind(request_fast_unwind)) {
58+
GetThreadStackTopAndBottom(false, &top, &bottom);
59+
stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
60+
} else
61+
stack->Unwind(kStackTraceMax, pc, 0, context, 0, 0, false);
62+
}

compiler-rt/lib/ubsan/ubsan_diag.cc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@
2626

2727
using namespace __ubsan;
2828

29-
void __ubsan::GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc,
30-
uptr bp, void *context, bool fast) {
31-
uptr top = 0;
32-
uptr bottom = 0;
33-
if (StackTrace::WillUseFastUnwind(fast)) {
34-
GetThreadStackTopAndBottom(false, &top, &bottom);
35-
stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
36-
} else
37-
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
38-
}
39-
4029
static void MaybePrintStackTrace(uptr pc, uptr bp) {
4130
// We assume that flags are already parsed, as UBSan runtime
4231
// will definitely be called when we print the first diagnostics message.

compiler-rt/lib/ubsan/ubsan_diag.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,6 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET);
234234
GET_CALLER_PC_BP; \
235235
ReportOptions Opts = {unrecoverable_handler, pc, bp}
236236

237-
void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
238-
void *context, bool fast);
239-
240237
/// \brief Instantiate this class before printing diagnostics in the error
241238
/// report. This class ensures that reports from different threads and from
242239
/// different sanitizers won't be mixed.

compiler-rt/lib/ubsan/ubsan_diag_standalone.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@
1414
#if CAN_SANITIZE_UB
1515
#include "ubsan_diag.h"
1616

17+
void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
18+
uptr pc, uptr bp, void *context, bool fast) {
19+
uptr top = 0;
20+
uptr bottom = 0;
21+
if (StackTrace::WillUseFastUnwind(fast)) {
22+
GetThreadStackTopAndBottom(false, &top, &bottom);
23+
stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
24+
} else
25+
stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
26+
}
27+
1728
using namespace __ubsan;
1829

1930
extern "C" {

0 commit comments

Comments
 (0)