diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2012-06-22 11:08:55 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2012-06-22 11:08:55 +0000 |
commit | 9ad7c32720dfa1287f8cfd481e5d583435178cae (patch) | |
tree | 8b4a7cbe0e7c77e522e2df6a19a804dd10b1febd /lib/tsan/rtl/tsan_sync.cc | |
parent | f4e8fc675ab52d0b3022847764a70ed7f03817bd (diff) |
tsan: do not call malloc/free in memory access handling routine.
This improves signal-/fork-safety of instrumented programs.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@158988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_sync.cc')
-rw-r--r-- | lib/tsan/rtl/tsan_sync.cc | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/tsan/rtl/tsan_sync.cc b/lib/tsan/rtl/tsan_sync.cc index b8ee589fb..ebe7df4aa 100644 --- a/lib/tsan/rtl/tsan_sync.cc +++ b/lib/tsan/rtl/tsan_sync.cc @@ -133,7 +133,16 @@ int SyncTab::PartIdx(uptr addr) { StackTrace::StackTrace() : n_() - , s_() { + , s_() + , c_() { +} + +StackTrace::StackTrace(uptr *buf, uptr cnt) + : n_() + , s_(buf) + , c_(cnt) { + CHECK_NE(buf, 0); + CHECK_NE(cnt, 0); } StackTrace::~StackTrace() { @@ -141,21 +150,26 @@ StackTrace::~StackTrace() { } void StackTrace::Reset() { - if (s_) { + if (s_ && !c_) { CHECK_NE(n_, 0); internal_free(s_); s_ = 0; - n_ = 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; - s_ = (uptr*)internal_alloc(MBlockStackTrace, cnt * sizeof(s_[0])); - REAL(memcpy)(s_, pcs, cnt * sizeof(s_[0])); + internal_memcpy(s_, pcs, cnt * sizeof(s_[0])); } void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) { @@ -163,7 +177,13 @@ void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) { n_ = thr->shadow_stack_pos - &thr->shadow_stack[0]; if (n_ + !!toppc == 0) return; - s_ = (uptr*)internal_alloc(MBlockStackTrace, (n_ + !!toppc) * sizeof(s_[0])); + if (c_) { + CHECK_NE(s_, 0); + CHECK_LE(n_ + !!toppc, c_); + } else { + s_ = (uptr*)internal_alloc(MBlockStackTrace, + (n_ + !!toppc) * sizeof(s_[0])); + } for (uptr i = 0; i < n_; i++) s_[i] = thr->shadow_stack[i]; if (toppc) { |