summaryrefslogtreecommitdiff
path: root/lib/tsan/rtl/tsan_stack_trace.cc
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-11-03 22:23:44 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-11-03 22:23:44 +0000
commit57f564f7ca442a0eaa2d58c2fe75fb8b0d8894f0 (patch)
tree3094671657aa787d39dfb30d24810d80bce1d27c /lib/tsan/rtl/tsan_stack_trace.cc
parente96c2212894f9345d3b0d8dba29da5e06b6e1cbe (diff)
[TSan] Use StackTrace from sanitizer_common where applicable
Summary: This change removes `__tsan::StackTrace` class. There are now three alternatives: # Lightweight `__sanitizer::StackTrace`, which doesn't own a buffer of PCs. It is used in functions that need stack traces in read-only mode, and helps to prevent unnecessary allocations/copies (e.g. for StackTraces fetched from StackDepot). # `__sanitizer::BufferedStackTrace`, which stores buffer of PCs in a constant array. It is used in TraceHeader (non-Go version) # `__tsan::VarSizeStackTrace`, which owns buffer of PCs, dynamically allocated via TSan internal allocator. Test Plan: compiler-rt test suite Reviewers: dvyukov, kcc Reviewed By: kcc Subscribers: llvm-commits, kcc Differential Revision: http://reviews.llvm.org/D6004 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@221194 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_stack_trace.cc')
-rw-r--r--lib/tsan/rtl/tsan_stack_trace.cc102
1 files changed, 21 insertions, 81 deletions
diff --git a/lib/tsan/rtl/tsan_stack_trace.cc b/lib/tsan/rtl/tsan_stack_trace.cc
index bf1efd444..ceca3f8e8 100644
--- a/lib/tsan/rtl/tsan_stack_trace.cc
+++ b/lib/tsan/rtl/tsan_stack_trace.cc
@@ -16,91 +16,31 @@
namespace __tsan {
-StackTrace::StackTrace()
- : n_()
- , s_()
- , c_() {
-}
-
-StackTrace::StackTrace(uptr *buf, uptr cnt)
- : n_()
- , s_(buf)
- , c_(cnt) {
- CHECK_NE(buf, 0);
- CHECK_NE(cnt, 0);
-}
-
-StackTrace::~StackTrace() {
- Reset();
-}
+VarSizeStackTrace::VarSizeStackTrace()
+ : StackTrace(nullptr, 0), trace_buffer(nullptr) {}
-void StackTrace::Reset() {
- if (s_ && !c_) {
- CHECK_NE(n_, 0);
- internal_free(s_);
- s_ = 0;
- }
- n_ = 0;
-}
-
-void StackTrace::Init(const uptr *pcs, uptr cnt) {
- Reset();
- if (cnt == 0)
- return;
- if (c_) {
- CHECK_NE(s_, 0);
- CHECK_LE(cnt, c_);
- } else {
- s_ = (uptr*)internal_alloc(MBlockStackTrace, cnt * sizeof(s_[0]));
- }
- n_ = cnt;
- internal_memcpy(s_, pcs, cnt * sizeof(s_[0]));
+VarSizeStackTrace::~VarSizeStackTrace() {
+ ResizeBuffer(0);
}
-void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) {
- Reset();
- n_ = thr->shadow_stack_pos - thr->shadow_stack;
- if (n_ + !!toppc == 0)
- return;
- uptr start = 0;
- if (c_) {
- CHECK_NE(s_, 0);
- if (n_ + !!toppc > c_) {
- start = n_ - c_ + !!toppc;
- n_ = c_ - !!toppc;
- }
- } else {
- // Cap potentially huge stacks.
- if (n_ + !!toppc > kTraceStackSize) {
- start = n_ - kTraceStackSize + !!toppc;
- n_ = kTraceStackSize - !!toppc;
- }
- s_ = (uptr*)internal_alloc(MBlockStackTrace,
- (n_ + !!toppc) * sizeof(s_[0]));
+void VarSizeStackTrace::ResizeBuffer(uptr new_size) {
+ if (trace_buffer) {
+ internal_free(trace_buffer);
}
- for (uptr i = 0; i < n_; i++)
- s_[i] = thr->shadow_stack[start + i];
- if (toppc) {
- s_[n_] = toppc;
- n_++;
- }
-}
-
-bool StackTrace::IsEmpty() const {
- return n_ == 0;
-}
-
-uptr StackTrace::Size() const {
- return n_;
-}
-
-uptr StackTrace::Get(uptr i) const {
- CHECK_LT(i, n_);
- return s_[i];
-}
-
-const uptr *StackTrace::Begin() const {
- return s_;
+ trace_buffer =
+ (new_size > 0)
+ ? (uptr *)internal_alloc(MBlockStackTrace,
+ new_size * sizeof(trace_buffer[0]))
+ : nullptr;
+ trace = trace_buffer;
+ size = new_size;
+}
+
+void VarSizeStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {
+ ResizeBuffer(cnt + !!extra_top_pc);
+ internal_memcpy(trace_buffer, pcs, cnt * sizeof(trace_buffer[0]));
+ if (extra_top_pc)
+ trace_buffer[cnt] = extra_top_pc;
}
} // namespace __tsan