From 16875b8c58c43e778fdf41b99134285052e5a5bb Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 14 Dec 2011 22:00:17 -0500 Subject: [PATCH] Make CreateStackTrace() more flexible. CreateStackTrace() can now optionally be asked to limit the maximum number of frames it tries to unwind. In conjunction, it can also be passed an already existing partial stack trace, and be asked to unwind more frames from it. --- src/apps/debugger/arch/Architecture.cpp | 33 +++++++++++++++++++------ src/apps/debugger/arch/Architecture.h | 4 ++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index 33e5460f7d..084b8ee690 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -94,18 +94,31 @@ Architecture::InitRegisterRules(CfaContext& context) const status_t Architecture::CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, - StackTrace*& _stackTrace) + StackTrace*& _stackTrace, int32 maxStackDepth, bool useExistingTrace) { BReference cpuStateReference(cpuState); - // create the object - StackTrace* stackTrace = new(std::nothrow) StackTrace; - if (stackTrace == NULL) - return B_NO_MEMORY; - ObjectDeleter stackTraceDeleter(stackTrace); - + StackTrace* stackTrace = NULL; + ObjectDeleter stackTraceDeleter; StackFrame* frame = NULL; + if (useExistingTrace) + stackTrace = _stackTrace; + else { + // create the object + stackTrace = new(std::nothrow) StackTrace; + if (stackTrace == NULL) + return B_NO_MEMORY; + stackTraceDeleter.SetTo(stackTrace); + } + + // if we're passed an already existing partial stack trace, + // attempt to continue building it from where it left off. + if (stackTrace->CountFrames() > 0) { + frame = stackTrace->FrameAt(stackTrace->CountFrames() - 1); + cpuState = frame->GetCpuState(); + } + while (cpuState != NULL) { // get the instruction pointer target_addr_t instructionPointer = cpuState->InstructionPointer(); @@ -169,11 +182,15 @@ Architecture::CreateStackTrace(Team* team, previousFrame->SetImage(image); previousFrame->SetFunction(function); - if (!stackTrace->AddFrame(previousFrame)) + if (!stackTrace->AddFrame(previousFrame)) { + delete previousFrame; return B_NO_MEMORY; + } frame = previousFrame; cpuState = previousCpuState; + if (--maxStackDepth == 0) + break; } stackTraceDeleter.Detach(); diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index d74d652344..1f0d40b306 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -100,7 +100,9 @@ public: status_t CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, - StackTrace*& _stackTrace); + StackTrace*& _stackTrace, + int32 maxStackDepth = -1, + bool useExistingTrace = false); // team is not locked protected: