Bug 1312883 - Use MozStackWalk to gather native stacks on Windows. r=gfritzsche,jchen,liuche

MozReview-Commit-ID: A2aZAL03FG2
This commit is contained in:
Mike Conley
2017-02-16 12:05:46 -05:00
parent 39eb226f83
commit a194e7116b
5 changed files with 69 additions and 9 deletions

View File

@@ -162,6 +162,12 @@ public:
void
ThreadStackHelper::GetStack(Stack& aStack)
{
GetStackInternal(aStack, /* aAppendNativeStack */ false);
}
void
ThreadStackHelper::GetStackInternal(Stack& aStack, bool aAppendNativeStack)
{
// Always run PrepareStackBuffer first to clear aStack
if (!PrepareStackBuffer(aStack)) {
@@ -195,6 +201,13 @@ ThreadStackHelper::GetStack(Stack& aStack)
MOZ_ASSERT(false);
return;
}
#ifdef _WIN64
AcquireStackWalkWorkaroundLock();
#endif
if (aAppendNativeStack) {
aStack.EnsureNativeFrameCapacity(Telemetry::HangStack::sMaxNativeFrames);
}
if (::SuspendThread(mThreadID) == DWORD(-1)) {
MOZ_ASSERT(false);
return;
@@ -209,6 +222,22 @@ ThreadStackHelper::GetStack(Stack& aStack)
FillStackBuffer();
}
#ifdef _WIN64
ReleaseStackWalkWorkaroundLock();
#endif
if (aAppendNativeStack) {
auto callback = [](uint32_t, void* aPC, void*, void* aClosure) {
Stack* stack = static_cast<Stack*>(aClosure);
stack->AppendNativeFrame(reinterpret_cast<uintptr_t>(aPC));
};
MozStackWalk(callback, /* skipFrames */ 0,
/* maxFrames */ Telemetry::HangStack::sMaxNativeFrames,
reinterpret_cast<void*>(&aStack),
reinterpret_cast<uintptr_t>(mThreadID), nullptr);
}
MOZ_ALWAYS_TRUE(::ResumeThread(mThreadID) != DWORD(-1));
#elif defined(XP_MACOSX)
@@ -236,10 +265,7 @@ void
ThreadStackHelper::GetNativeStack(Stack& aStack)
{
#ifdef MOZ_THREADSTACKHELPER_NATIVE
// Get pseudostack first and fill the thread context.
GetStack(aStack);
// TODO: walk the saved stack frames.
GetStackInternal(aStack, /* aAppendNativeStack */ true);
#endif // MOZ_THREADSTACKHELPER_NATIVE
}