Add CPU state at time of function call to Thread.
- When we detect that we're stepping over a function call, also store the CPU state at the time it occurred. This information is needed in order to correctly reconstruct target addresses later since some operands may be register-based. - Add the aforementioned CPU state to CreateFrame()'s arguments and adjust implementations and callers accordingly.
This commit is contained in:
parent
04c919f9d6
commit
029fcc4ad6
@ -95,7 +95,8 @@ status_t
|
||||
Architecture::CreateStackTrace(Team* team,
|
||||
ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
|
||||
StackTrace*& _stackTrace, target_addr_t returnFunctionAddress,
|
||||
int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo)
|
||||
CpuState* returnFunctionState, int32 maxStackDepth, bool useExistingTrace,
|
||||
bool getFullFrameInfo)
|
||||
{
|
||||
BReference<CpuState> cpuStateReference(cpuState);
|
||||
|
||||
@ -163,7 +164,8 @@ Architecture::CreateStackTrace(Team* team,
|
||||
if (function != NULL) {
|
||||
status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
|
||||
->CreateFrame(image, function, cpuState, getFullFrameInfo,
|
||||
nextFrame == NULL ? returnFunctionAddress : 0, frame,
|
||||
nextFrame == NULL ? returnFunctionAddress : 0,
|
||||
nextFrame == NULL ? returnFunctionState : 0, frame,
|
||||
previousCpuState);
|
||||
if (error != B_OK && error != B_UNSUPPORTED)
|
||||
break;
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
CpuState* cpuState,
|
||||
StackTrace*& _stackTrace,
|
||||
target_addr_t returnFunctionAddress,
|
||||
CpuState* returnFunctionState,
|
||||
int32 maxStackDepth = -1,
|
||||
bool useExistingTrace = false,
|
||||
bool getFullFrameInfo = true);
|
||||
|
@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
|
||||
|
||||
if (stackTrace == NULL && cpuState != NULL) {
|
||||
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0, NULL, 1,
|
||||
false, false) == B_OK) {
|
||||
stackTraceReference.SetTo(stackTrace, true);
|
||||
}
|
||||
@ -485,6 +485,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
|
||||
"%#" B_PRIx64 "\n", info.Address() + info.Size());
|
||||
|
||||
fThread->SetExecutedSubroutine(info.TargetAddress());
|
||||
fThread->SetSubroutineCpuState(cpuState);
|
||||
if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
|
||||
return false;
|
||||
|
||||
@ -566,8 +567,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
|
||||
|
||||
if (stackTrace == NULL && cpuState != NULL) {
|
||||
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
|
||||
false, false) == B_OK) {
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0,
|
||||
NULL, 1, false, false) == B_OK) {
|
||||
stackTraceReference.SetTo(stackTrace, true);
|
||||
}
|
||||
}
|
||||
@ -653,8 +654,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
|
||||
|
||||
if (stackTrace == NULL && cpuState != NULL) {
|
||||
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1,
|
||||
false, false) == B_OK) {
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0,
|
||||
NULL, 1, false, false) == B_OK) {
|
||||
stackTraceReference.SetTo(stackTrace, true);
|
||||
}
|
||||
}
|
||||
@ -686,7 +687,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
|
||||
if (stackTrace == NULL && cpuState != NULL) {
|
||||
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
|
||||
fThread->GetTeam(), this, cpuState, stackTrace, 0,
|
||||
1, false, false) == B_OK) {
|
||||
NULL, 1, false, false) == B_OK) {
|
||||
stackTraceReference.SetTo(stackTrace, true);
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ status_t
|
||||
DebuggerImageDebugInfo::CreateFrame(Image* image,
|
||||
FunctionInstance* functionInstance, CpuState* cpuState,
|
||||
bool getFullFrameInfo, target_addr_t returnFunctionAddress,
|
||||
StackFrame*& _previousFrame, CpuState*& _previousCpuState)
|
||||
CpuState* returnFunctionState, StackFrame*& _previousFrame,
|
||||
CpuState*& _previousCpuState)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
CpuState* cpuState,
|
||||
bool getFullFrameInfo,
|
||||
target_addr_t returnFunctionAddress,
|
||||
CpuState* returnFunctionState,
|
||||
StackFrame*& _previousFrame,
|
||||
CpuState*& _previousCpuState);
|
||||
virtual status_t GetStatement(FunctionDebugInfo* function,
|
||||
|
@ -523,7 +523,8 @@ status_t
|
||||
DwarfImageDebugInfo::CreateFrame(Image* image,
|
||||
FunctionInstance* functionInstance, CpuState* cpuState,
|
||||
bool getFullFrameInfo, target_addr_t returnFunctionAddress,
|
||||
StackFrame*& _frame, CpuState*& _previousCpuState)
|
||||
CpuState* returnFunctionState, StackFrame*& _frame,
|
||||
CpuState*& _previousCpuState)
|
||||
{
|
||||
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
|
||||
functionInstance->GetFunctionDebugInfo());
|
||||
@ -1091,7 +1092,8 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
|
||||
|
||||
status_t
|
||||
DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
|
||||
Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory)
|
||||
CpuState* returnFunctionState, Image* image, StackFrame* frame,
|
||||
DwarfStackFrameDebugInfo& factory)
|
||||
{
|
||||
if (!image->ContainsAddress(returnFunctionAddress)) {
|
||||
// our current image doesn't contain the target function,
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
CpuState* cpuState,
|
||||
bool getFullFrameInfo,
|
||||
target_addr_t returnFunctionAddress,
|
||||
CpuState* returnFunctionState,
|
||||
StackFrame*& _frame,
|
||||
CpuState*& _previousCpuState);
|
||||
virtual status_t GetStatement(FunctionDebugInfo* function,
|
||||
@ -106,6 +107,7 @@ private:
|
||||
|
||||
status_t _CreateReturnValue(
|
||||
target_addr_t returnFunctionAddress,
|
||||
CpuState* returnFunctionState,
|
||||
Image* image,
|
||||
StackFrame* frame,
|
||||
DwarfStackFrameDebugInfo& factory);
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
CpuState* cpuState,
|
||||
bool getFullFrameInfo,
|
||||
target_addr_t returnFunctionAddress,
|
||||
CpuState* returnFunctionState,
|
||||
StackFrame*& _Frame,
|
||||
CpuState*& _previousCpuState) = 0;
|
||||
// returns reference to previous frame
|
||||
|
@ -59,7 +59,8 @@ GetStackTraceJob::Do()
|
||||
StackTrace* stackTrace;
|
||||
status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this,
|
||||
fCpuState, stackTrace, fThread->ExecutedSubroutine()
|
||||
? fThread->SubroutineAddress() : 0);
|
||||
? fThread->SubroutineAddress() : 0, fThread->ExecutedSubroutine()
|
||||
? fThread->SubroutineCpuState() : NULL);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
BReference<StackTrace> stackTraceReference(stackTrace, true);
|
||||
|
@ -19,6 +19,7 @@ Thread::Thread(Team* team, thread_id threadID)
|
||||
fState(THREAD_STATE_UNKNOWN),
|
||||
fExecutedSubroutine(false),
|
||||
fSubroutineAddress(0),
|
||||
fSubroutineState(NULL),
|
||||
fStoppedReason(THREAD_STOPPED_UNKNOWN),
|
||||
fCpuState(NULL),
|
||||
fStackTrace(NULL)
|
||||
@ -32,6 +33,8 @@ Thread::~Thread()
|
||||
fCpuState->ReleaseReference();
|
||||
if (fStackTrace != NULL)
|
||||
fStackTrace->ReleaseReference();
|
||||
if (fSubroutineState != NULL)
|
||||
fSubroutineState->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
@ -121,3 +124,13 @@ Thread::SetExecutedSubroutine(target_addr_t address)
|
||||
fSubroutineAddress = address;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Thread::SetSubroutineCpuState(CpuState* state)
|
||||
{
|
||||
if (fSubroutineState != NULL)
|
||||
fSubroutineState->ReleaseReference();
|
||||
|
||||
fSubroutineState = state;
|
||||
fSubroutineState->AcquireReference();
|
||||
}
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
target_addr_t SubroutineAddress() const
|
||||
{ return fSubroutineAddress; }
|
||||
void SetExecutedSubroutine(target_addr_t address);
|
||||
CpuState* SubroutineCpuState() const
|
||||
{ return fSubroutineState; }
|
||||
void SetSubroutineCpuState(CpuState* state);
|
||||
|
||||
private:
|
||||
Team* fTeam;
|
||||
@ -82,6 +85,7 @@ private:
|
||||
uint32 fState;
|
||||
bool fExecutedSubroutine;
|
||||
target_addr_t fSubroutineAddress;
|
||||
CpuState* fSubroutineState;
|
||||
uint32 fStoppedReason;
|
||||
BString fStoppedReasonInfo;
|
||||
CpuState* fCpuState;
|
||||
|
Loading…
Reference in New Issue
Block a user