Fix unwinding of partial stack traces.
- Architecture::CreateStackTrace() now uses the last frame's PreviousCpuState() as the basis to continue unwinding when passed a partial trace to continue from, rather than the (incorrect) actual cpu state of that frame, which would have resulted in the last frame being duplicated in the trace. - Renamed variables to be more clear.
This commit is contained in:
parent
a9bec97e47
commit
26334a8a66
@ -100,7 +100,7 @@ Architecture::CreateStackTrace(Team* team,
|
||||
|
||||
StackTrace* stackTrace = NULL;
|
||||
ObjectDeleter<StackTrace> stackTraceDeleter;
|
||||
StackFrame* frame = NULL;
|
||||
StackFrame* nextFrame = NULL;
|
||||
|
||||
if (useExistingTrace)
|
||||
stackTrace = _stackTrace;
|
||||
@ -115,8 +115,8 @@ Architecture::CreateStackTrace(Team* team,
|
||||
// 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();
|
||||
nextFrame = stackTrace->FrameAt(stackTrace->CountFrames() - 1);
|
||||
cpuState = nextFrame->GetPreviousCpuState();
|
||||
}
|
||||
|
||||
while (cpuState != NULL) {
|
||||
@ -152,42 +152,42 @@ Architecture::CreateStackTrace(Team* team,
|
||||
|
||||
// If the CPU state's instruction pointer is actually the return address
|
||||
// of the next frame, we let the architecture fix that.
|
||||
if (frame != NULL
|
||||
&& frame->ReturnAddress() == cpuState->InstructionPointer()) {
|
||||
UpdateStackFrameCpuState(frame, image,
|
||||
if (nextFrame != NULL
|
||||
&& nextFrame->ReturnAddress() == cpuState->InstructionPointer()) {
|
||||
UpdateStackFrameCpuState(nextFrame, image,
|
||||
functionDebugInfo, cpuState);
|
||||
}
|
||||
|
||||
// create the frame using the debug info
|
||||
StackFrame* previousFrame = NULL;
|
||||
StackFrame* frame = NULL;
|
||||
CpuState* previousCpuState = NULL;
|
||||
if (function != NULL) {
|
||||
status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
|
||||
->CreateFrame(image, function, cpuState, previousFrame,
|
||||
->CreateFrame(image, function, cpuState, frame,
|
||||
previousCpuState);
|
||||
if (error != B_OK && error != B_UNSUPPORTED)
|
||||
break;
|
||||
}
|
||||
|
||||
// If we have no frame yet, let the architecture create it.
|
||||
if (previousFrame == NULL) {
|
||||
if (frame == NULL) {
|
||||
status_t error = CreateStackFrame(image, functionDebugInfo,
|
||||
cpuState, frame == NULL, previousFrame, previousCpuState);
|
||||
cpuState, nextFrame == NULL, frame, previousCpuState);
|
||||
if (error != B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
cpuStateReference.SetTo(previousCpuState, true);
|
||||
|
||||
previousFrame->SetImage(image);
|
||||
previousFrame->SetFunction(function);
|
||||
frame->SetImage(image);
|
||||
frame->SetFunction(function);
|
||||
|
||||
if (!stackTrace->AddFrame(previousFrame)) {
|
||||
delete previousFrame;
|
||||
if (!stackTrace->AddFrame(frame)) {
|
||||
delete frame;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
frame = previousFrame;
|
||||
frame = nextFrame;
|
||||
cpuState = previousCpuState;
|
||||
if (--maxStackDepth == 0)
|
||||
break;
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
virtual status_t CreateStackFrame(Image* image,
|
||||
FunctionDebugInfo* function,
|
||||
CpuState* cpuState, bool isTopFrame,
|
||||
StackFrame*& _previousFrame,
|
||||
StackFrame*& _frame,
|
||||
CpuState*& _previousCpuState) = 0;
|
||||
// returns reference to previous frame
|
||||
// and CPU state; returned CPU state
|
||||
|
@ -265,7 +265,7 @@ ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size,
|
||||
|
||||
status_t
|
||||
ArchitectureX86::CreateStackFrame(Image* image, FunctionDebugInfo* function,
|
||||
CpuState* _cpuState, bool isTopFrame, StackFrame*& _previousFrame,
|
||||
CpuState* _cpuState, bool isTopFrame, StackFrame*& _frame,
|
||||
CpuState*& _previousCpuState)
|
||||
{
|
||||
CpuStateX86* cpuState = dynamic_cast<CpuStateX86*>(_cpuState);
|
||||
@ -382,11 +382,12 @@ ArchitectureX86::CreateStackFrame(Image* image, FunctionDebugInfo* function,
|
||||
previousCpuState->SetIntRegister(X86_REGISTER_EBP,
|
||||
previousFramePointer);
|
||||
previousCpuState->SetIntRegister(X86_REGISTER_EIP, returnAddress);
|
||||
frame->SetPreviousCpuState(previousCpuState);
|
||||
}
|
||||
|
||||
frame->SetReturnAddress(returnAddress);
|
||||
|
||||
_previousFrame = frameReference.Detach();
|
||||
_frame = frameReference.Detach();
|
||||
_previousCpuState = previousCpuState;
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -495,7 +495,7 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address)
|
||||
status_t
|
||||
DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
FunctionInstance* functionInstance, CpuState* cpuState,
|
||||
StackFrame*& _previousFrame, CpuState*& _previousCpuState)
|
||||
StackFrame*& _frame, CpuState*& _previousCpuState)
|
||||
{
|
||||
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
|
||||
functionInstance->GetFunctionDebugInfo());
|
||||
@ -634,9 +634,11 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
instructionPointer, functionInstance->Address() - fRelocationDelta,
|
||||
subprogramEntry->Variables(), subprogramEntry->Blocks());
|
||||
|
||||
_previousFrame = frameReference.Detach();
|
||||
_frame = frameReference.Detach();
|
||||
_previousCpuState = previousCpuStateReference.Detach();
|
||||
|
||||
frame->SetPreviousCpuState(_previousCpuState);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
virtual status_t CreateFrame(Image* image,
|
||||
FunctionInstance* functionInstance,
|
||||
CpuState* cpuState,
|
||||
StackFrame*& _previousFrame,
|
||||
StackFrame*& _frame,
|
||||
CpuState*& _previousCpuState);
|
||||
virtual status_t GetStatement(FunctionDebugInfo* function,
|
||||
target_addr_t address,
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
virtual status_t CreateFrame(Image* image,
|
||||
FunctionInstance* functionInstance,
|
||||
CpuState* cpuState,
|
||||
StackFrame*& _previousFrame,
|
||||
StackFrame*& _Frame,
|
||||
CpuState*& _previousCpuState) = 0;
|
||||
// returns reference to previous frame
|
||||
// and CPU state; returned CPU state
|
||||
|
Loading…
Reference in New Issue
Block a user