summaryrefslogtreecommitdiff
path: root/lib/tsan/rtl/tsan_sync.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-06-22 11:08:55 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-06-22 11:08:55 +0000
commit9ad7c32720dfa1287f8cfd481e5d583435178cae (patch)
tree8b4a7cbe0e7c77e522e2df6a19a804dd10b1febd /lib/tsan/rtl/tsan_sync.cc
parentf4e8fc675ab52d0b3022847764a70ed7f03817bd (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.cc32
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) {