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.
This commit is contained in:
Rene Gollent 2011-12-14 22:00:17 -05:00
parent d3e3195112
commit 16875b8c58
2 changed files with 28 additions and 9 deletions

View File

@ -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<CpuState> cpuStateReference(cpuState);
// create the object
StackTrace* stackTrace = new(std::nothrow) StackTrace;
if (stackTrace == NULL)
return B_NO_MEMORY;
ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
StackTrace* stackTrace = NULL;
ObjectDeleter<StackTrace> 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();

View File

@ -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: