Bug 1050445 - Part 4: Take stack snapshots. r=njn

--HG--
extra : rebase_source : 0a8ec331cc320c4a6b8289824c3bc1d84a571309
This commit is contained in:
Eric Rahm 2014-08-13 12:37:40 -07:00
parent 23e1f03872
commit 6121db7d4b
2 changed files with 41 additions and 1 deletions

View File

@ -11,6 +11,10 @@
#include "nsAutoPtr.h"
#ifndef MOZ_CALLSTACK_DISABLED
#include "nsStackWalk.h"
#endif
#include "mozilla/CondVar.h"
#include "mozilla/DeadlockDetector.h"
#include "mozilla/ReentrantMonitor.h"
@ -41,6 +45,30 @@ unsigned BlockingResourceBase::sResourceAcqnChainFrontTPI = (unsigned)-1;
BlockingResourceBase::DDT* BlockingResourceBase::sDeadlockDetector;
void
BlockingResourceBase::StackWalkCallback(void* aPc, void* aSp, void* aClosure)
{
#ifndef MOZ_CALLSTACK_DISABLED
AcquisitionState* state = (AcquisitionState*)aClosure;
state->AppendElement(aPc);
#endif
}
void
BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
{
#ifndef MOZ_CALLSTACK_DISABLED
const uint32_t kSkipFrames = 2;
aState.Clear();
// NB: Ignore the return value, there's nothing useful we can do if this
// this fails.
NS_StackWalk(StackWalkCallback, kSkipFrames,
24, &aState, 0, nullptr);
#endif
}
/**
* PrintCycle
* Append to |aOut| detailed information about the circular
@ -188,6 +216,11 @@ BlockingResourceBase::CheckAcquire()
return;
}
#ifndef MOZ_CALLSTACK_DISABLED
// Update the current stack before printing.
GetStackTrace(mAcquired);
#endif
fputs("###!!! ERROR: Potential deadlock detected:\n", stderr);
nsAutoCString out("Potential deadlock detected:\n");
bool maybeImminent = PrintCycle(cycle, out);
@ -225,7 +258,11 @@ BlockingResourceBase::Acquire()
#ifdef MOZ_CALLSTACK_DISABLED
mAcquired = true;
#else
// TODO(ER): take stack snapshot
// Take a stack snapshot.
GetStackTrace(mAcquired);
if (mFirstSeen.IsEmpty()) {
mFirstSeen = mAcquired;
}
#endif
}

View File

@ -319,6 +319,9 @@ private:
*/
static void Shutdown();
static void StackWalkCallback(void* aPc, void* aSp, void* aClosure);
static void GetStackTrace(AcquisitionState& aState);
# ifdef MOZILLA_INTERNAL_API
// so it can call BlockingResourceBase::Shutdown()
friend void LogTerm();