} // namespace __asan
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
- uptr pc, uptr bp, void *context, bool fast) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
using namespace __asan;
#if SANITIZER_WINDOWS
stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
#else
AsanThread *t;
- stack->size = 0;
+ size = 0;
if (LIKELY(asan_inited)) {
if ((t = GetCurrentThread()) && !t->isUnwinding()) {
uptr stack_top = t->stack_top();
uptr stack_bottom = t->stack_bottom();
ScopedUnwinding unwind_scope(t);
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
- if (StackTrace::WillUseFastUnwind(fast))
- stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom,
- true);
+ if (StackTrace::WillUseFastUnwind(request_fast))
+ Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
else
- stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
}
- } else if (!t && !fast) {
+ } else if (!t && !request_fast) {
/* If GetCurrentThread() has failed, try to do slow unwind anyways. */
- stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
+ Unwind(max_depth, pc, bp, context, 0, 0, false);
}
}
#endif // SANITIZER_WINDOWS
} // namespace __hwasan
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
- uptr bp, void *context,
- bool request_fast_unwind) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
using namespace __hwasan;
Thread *t = GetCurrentThread();
if (!t) {
// the thread is still being created.
- stack->size = 0;
+ size = 0;
return;
}
- if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
+ if (!StackTrace::WillUseFastUnwind(request_fast)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
- return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind);
+ return Unwind(max_depth, pc, bp, context, 0, 0, request_fast);
}
- if (StackTrace::WillUseFastUnwind(request_fast_unwind))
- stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
- true);
+ if (StackTrace::WillUseFastUnwind(request_fast))
+ Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true);
else
- stack->Unwind(max_s, pc, 0, context, 0, 0, false);
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
}
// Interface.
} // namespace __lsan
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
- uptr pc, uptr bp, void *context, bool fast) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
using namespace __lsan;
uptr stack_top = 0, stack_bottom = 0;
ThreadContext *t;
- if (StackTrace::WillUseFastUnwind(fast) &&
+ if (StackTrace::WillUseFastUnwind(request_fast) &&
(t = CurrentThreadContext())) {
stack_top = t->stack_end();
stack_bottom = t->stack_begin();
}
if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
- if (StackTrace::WillUseFastUnwind(fast))
- stack->Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
+ if (StackTrace::WillUseFastUnwind(request_fast))
+ Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
else
- stack->Unwind(max_depth, pc, 0, context, 0, 0, false);
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
}
}
} // namespace __msan
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc,
- uptr bp, void *context,
- bool request_fast_unwind) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
using namespace __msan;
MsanThread *t = GetCurrentThread();
- if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
+ if (!t || !StackTrace::WillUseFastUnwind(request_fast)) {
// Block reports from our interceptors during _Unwind_Backtrace.
SymbolizerScope sym_scope;
- return stack->Unwind(max_s, pc, bp, context, 0, 0, false);
+ return Unwind(max_depth, pc, bp, context, 0, 0, false);
}
- if (StackTrace::WillUseFastUnwind(request_fast_unwind))
- stack->Unwind(max_s, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
- true);
+ if (StackTrace::WillUseFastUnwind(request_fast))
+ Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true);
else
- stack->Unwind(max_s, pc, 0, context, 0, 0, false);
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
}
// Interface.
namespace __sanitizer {
struct BufferedStackTrace;
-// Get the stack trace with the given pc and bp.
-// The pc will be in the position 0 of the resulting stack trace.
-// The bp may refer to the current frame or to the caller's frame.
-void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
- void *context, bool request_fast_unwind);
static const u32 kStackTraceMax = 256;
void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0);
+ // Get the stack trace with the given pc and bp.
+ // The pc will be in the position 0 of the resulting stack trace.
+ // The bp may refer to the current frame or to the caller's frame.
void Unwind(uptr pc, uptr bp, void *context, bool request_fast,
u32 max_depth = kStackTraceMax) {
top_frame_bp = (max_depth > 0) ? bp : 0;
size = max_depth;
return;
}
- GetStackTrace(this, max_depth, pc, bp, context, request_fast);
+ UnwindImpl(pc, bp, context, request_fast, max_depth);
}
void Unwind(u32 max_depth, uptr pc, uptr bp, void *context, uptr stack_top,
}
private:
+ // Every runtime defines its own implementation of this method
+ void UnwindImpl(uptr pc, uptr bp, void *context, bool request_fast,
+ u32 max_depth);
+
+ // UnwindFast/Slow have platform-specific implementations
void UnwindFast(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom,
u32 max_depth);
void UnwindSlow(uptr pc, u32 max_depth);
void UnwindSlow(uptr pc, void *context, u32 max_depth);
+
void PopStackFrames(uptr count);
uptr LocatePcInTrace(uptr pc);
} // namespace __tsan
#if !SANITIZER_GO
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
- uptr pc, uptr bp, void *context,
- bool request_fast_unwind) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
uptr top = 0;
uptr bottom = 0;
- if (StackTrace::WillUseFastUnwind(request_fast_unwind)) {
+ if (StackTrace::WillUseFastUnwind(request_fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
+ Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
} else
- stack->Unwind(kStackTraceMax, pc, 0, context, 0, 0, false);
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
}
-#endif
+#endif // SANITIZER_GO
using namespace __ubsan;
-void __sanitizer::GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
- uptr pc, uptr bp, void *context, bool fast) {
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
uptr top = 0;
uptr bottom = 0;
- if (StackTrace::WillUseFastUnwind(fast)) {
+ if (StackTrace::WillUseFastUnwind(request_fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
+ Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
} else
- stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
+ Unwind(max_depth, pc, bp, context, 0, 0, false);
}
extern "C" {
// UNSUPPORTED: darwin
+// TODO(yln): temporary failing due to refactoring
+// XFAIL: ubsan
+
#include <sanitizer/common_interface_defs.h>
static inline void FooBarBaz() {