summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2014-03-19 12:49:46 +0000
committerDmitry Vyukov <dvyukov@google.com>2014-03-19 12:49:46 +0000
commit855ed281997048463eadbef15d7a04abd84c1c5c (patch)
tree5c75f860c230335b6da2a7619802276bd2827665
parent8ee651d7de366459e94ccb58e51864e41523457d (diff)
tsan: fix large stack frame in deadlock detector
In member function 'virtual void __sanitizer::DD::MutexBeforeLock(__sanitizer::DDCallback*, __sanitizer::DDMutex*, bool)': error: the frame size of 544 bytes is larger than 512 bytes [-Werror=frame-larger-than=] The code is now [arguably] better as well. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@204227 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_deadlock_detector1.cc50
1 files changed, 28 insertions, 22 deletions
diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector1.cc b/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
index 0e920d8a6..f936af609 100644
--- a/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
+++ b/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
@@ -54,6 +54,7 @@ struct DD : public DDetector {
DDReport *GetReport(DDCallback *cb);
void MutexEnsureID(DDLogicalThread *lt, DDMutex *m);
+ void ReportDeadlock(DDCallback *cb, DDMutex *m);
};
DDetector *DDetector::Create(const DDFlags *flags) {
@@ -109,28 +110,33 @@ void DD::MutexBeforeLock(DDCallback *cb,
if (dd.onLockBefore(&lt->dd, m->id)) {
// Actually add this edge now so that we have all the stack traces.
dd.addEdges(&lt->dd, m->id, cb->Unwind());
- uptr path[10];
- uptr len = dd.findPathToLock(&lt->dd, m->id, path, ARRAY_SIZE(path));
- CHECK_GT(len, 0U); // Hm.. cycle of 10 locks? I'd like to see that.
- CHECK_EQ(m->id, path[0]);
- lt->report_pending = true;
- DDReport *rep = &lt->rep;
- rep->n = len;
- for (uptr i = 0; i < len; i++) {
- uptr from = path[i];
- uptr to = path[(i + 1) % len];
- DDMutex *m0 = (DDMutex*)dd.getData(from);
- DDMutex *m1 = (DDMutex*)dd.getData(to);
-
- u32 stk_from = 0, stk_to = 0;
- dd.findEdge(from, to, &stk_from, &stk_to);
- // Printf("Edge: %zd=>%zd: %u/%u\n", from, to, stk_from, stk_to);
- rep->loop[i].thr_ctx = 0; // don't know
- rep->loop[i].mtx_ctx0 = m0->ctx;
- rep->loop[i].mtx_ctx1 = m1->ctx;
- rep->loop[i].stk[0] = stk_from;
- rep->loop[i].stk[1] = stk_to;
- }
+ ReportDeadlock(cb, m);
+ }
+}
+
+void DD::ReportDeadlock(DDCallback *cb, DDMutex *m) {
+ DDLogicalThread *lt = cb->lt;
+ uptr path[10];
+ uptr len = dd.findPathToLock(&lt->dd, m->id, path, ARRAY_SIZE(path));
+ CHECK_GT(len, 0U); // Hm.. cycle of 10 locks? I'd like to see that.
+ CHECK_EQ(m->id, path[0]);
+ lt->report_pending = true;
+ DDReport *rep = &lt->rep;
+ rep->n = len;
+ for (uptr i = 0; i < len; i++) {
+ uptr from = path[i];
+ uptr to = path[(i + 1) % len];
+ DDMutex *m0 = (DDMutex*)dd.getData(from);
+ DDMutex *m1 = (DDMutex*)dd.getData(to);
+
+ u32 stk_from = 0, stk_to = 0;
+ dd.findEdge(from, to, &stk_from, &stk_to);
+ // Printf("Edge: %zd=>%zd: %u/%u\n", from, to, stk_from, stk_to);
+ rep->loop[i].thr_ctx = 0; // don't know
+ rep->loop[i].mtx_ctx0 = m0->ctx;
+ rep->loop[i].mtx_ctx1 = m1->ctx;
+ rep->loop[i].stk[0] = stk_from;
+ rep->loop[i].stk[1] = stk_to;
}
}