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:
Rene Gollent
2013-03-26 18:50:44 -04:00
parent 04c919f9d6
commit 029fcc4ad6
11 changed files with 41 additions and 12 deletions
+4 -2
View File
@@ -95,7 +95,8 @@ status_t
Architecture::CreateStackTrace(Team* team, Architecture::CreateStackTrace(Team* team,
ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
StackTrace*& _stackTrace, target_addr_t returnFunctionAddress, StackTrace*& _stackTrace, target_addr_t returnFunctionAddress,
int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo) CpuState* returnFunctionState, int32 maxStackDepth, bool useExistingTrace,
bool getFullFrameInfo)
{ {
BReference<CpuState> cpuStateReference(cpuState); BReference<CpuState> cpuStateReference(cpuState);
@@ -163,7 +164,8 @@ Architecture::CreateStackTrace(Team* team,
if (function != NULL) { if (function != NULL) {
status_t error = functionDebugInfo->GetSpecificImageDebugInfo() status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
->CreateFrame(image, function, cpuState, getFullFrameInfo, ->CreateFrame(image, function, cpuState, getFullFrameInfo,
nextFrame == NULL ? returnFunctionAddress : 0, frame, nextFrame == NULL ? returnFunctionAddress : 0,
nextFrame == NULL ? returnFunctionState : 0, frame,
previousCpuState); previousCpuState);
if (error != B_OK && error != B_UNSUPPORTED) if (error != B_OK && error != B_UNSUPPORTED)
break; break;
+1
View File
@@ -111,6 +111,7 @@ public:
CpuState* cpuState, CpuState* cpuState,
StackTrace*& _stackTrace, StackTrace*& _stackTrace,
target_addr_t returnFunctionAddress, target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
int32 maxStackDepth = -1, int32 maxStackDepth = -1,
bool useExistingTrace = false, bool useExistingTrace = false,
bool getFullFrameInfo = true); bool getFullFrameInfo = true);
@@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
if (stackTrace == NULL && cpuState != NULL) { if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, fThread->GetTeam(), this, cpuState, stackTrace, 0, NULL, 1,
false, false) == B_OK) { false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
@@ -485,6 +485,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
"%#" B_PRIx64 "\n", info.Address() + info.Size()); "%#" B_PRIx64 "\n", info.Address() + info.Size());
fThread->SetExecutedSubroutine(info.TargetAddress()); fThread->SetExecutedSubroutine(info.TargetAddress());
fThread->SetSubroutineCpuState(cpuState);
if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK) if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
return false; return false;
@@ -566,8 +567,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
if (stackTrace == NULL && cpuState != NULL) { if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, fThread->GetTeam(), this, cpuState, stackTrace, 0,
false, false) == B_OK) { NULL, 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
} }
@@ -653,8 +654,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
if (stackTrace == NULL && cpuState != NULL) { if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, fThread->GetTeam(), this, cpuState, stackTrace, 0,
false, false) == B_OK) { NULL, 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
} }
@@ -686,7 +687,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
if (stackTrace == NULL && cpuState != NULL) { if (stackTrace == NULL && cpuState != NULL) {
if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
fThread->GetTeam(), this, cpuState, stackTrace, 0, fThread->GetTeam(), this, cpuState, stackTrace, 0,
1, false, false) == B_OK) { NULL, 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
} }
@@ -69,7 +69,8 @@ status_t
DebuggerImageDebugInfo::CreateFrame(Image* image, DebuggerImageDebugInfo::CreateFrame(Image* image,
FunctionInstance* functionInstance, CpuState* cpuState, FunctionInstance* functionInstance, CpuState* cpuState,
bool getFullFrameInfo, target_addr_t returnFunctionAddress, bool getFullFrameInfo, target_addr_t returnFunctionAddress,
StackFrame*& _previousFrame, CpuState*& _previousCpuState) CpuState* returnFunctionState, StackFrame*& _previousFrame,
CpuState*& _previousCpuState)
{ {
return B_UNSUPPORTED; return B_UNSUPPORTED;
} }
@@ -37,6 +37,7 @@ public:
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
StackFrame*& _previousFrame, StackFrame*& _previousFrame,
CpuState*& _previousCpuState); CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function, virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -523,7 +523,8 @@ status_t
DwarfImageDebugInfo::CreateFrame(Image* image, DwarfImageDebugInfo::CreateFrame(Image* image,
FunctionInstance* functionInstance, CpuState* cpuState, FunctionInstance* functionInstance, CpuState* cpuState,
bool getFullFrameInfo, target_addr_t returnFunctionAddress, bool getFullFrameInfo, target_addr_t returnFunctionAddress,
StackFrame*& _frame, CpuState*& _previousCpuState) CpuState* returnFunctionState, StackFrame*& _frame,
CpuState*& _previousCpuState)
{ {
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>( DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
functionInstance->GetFunctionDebugInfo()); functionInstance->GetFunctionDebugInfo());
@@ -1091,7 +1092,8 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
status_t status_t
DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress, DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory) CpuState* returnFunctionState, Image* image, StackFrame* frame,
DwarfStackFrameDebugInfo& factory)
{ {
if (!image->ContainsAddress(returnFunctionAddress)) { if (!image->ContainsAddress(returnFunctionAddress)) {
// our current image doesn't contain the target function, // our current image doesn't contain the target function,
@@ -65,6 +65,7 @@ public:
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
StackFrame*& _frame, StackFrame*& _frame,
CpuState*& _previousCpuState); CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function, virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -106,6 +107,7 @@ private:
status_t _CreateReturnValue( status_t _CreateReturnValue(
target_addr_t returnFunctionAddress, target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
Image* image, Image* image,
StackFrame* frame, StackFrame* frame,
DwarfStackFrameDebugInfo& factory); DwarfStackFrameDebugInfo& factory);
@@ -57,6 +57,7 @@ public:
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
StackFrame*& _Frame, StackFrame*& _Frame,
CpuState*& _previousCpuState) = 0; CpuState*& _previousCpuState) = 0;
// returns reference to previous frame // returns reference to previous frame
+2 -1
View File
@@ -59,7 +59,8 @@ GetStackTraceJob::Do()
StackTrace* stackTrace; StackTrace* stackTrace;
status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this, status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this,
fCpuState, stackTrace, fThread->ExecutedSubroutine() fCpuState, stackTrace, fThread->ExecutedSubroutine()
? fThread->SubroutineAddress() : 0); ? fThread->SubroutineAddress() : 0, fThread->ExecutedSubroutine()
? fThread->SubroutineCpuState() : NULL);
if (error != B_OK) if (error != B_OK)
return error; return error;
BReference<StackTrace> stackTraceReference(stackTrace, true); BReference<StackTrace> stackTraceReference(stackTrace, true);
+13
View File
@@ -19,6 +19,7 @@ Thread::Thread(Team* team, thread_id threadID)
fState(THREAD_STATE_UNKNOWN), fState(THREAD_STATE_UNKNOWN),
fExecutedSubroutine(false), fExecutedSubroutine(false),
fSubroutineAddress(0), fSubroutineAddress(0),
fSubroutineState(NULL),
fStoppedReason(THREAD_STOPPED_UNKNOWN), fStoppedReason(THREAD_STOPPED_UNKNOWN),
fCpuState(NULL), fCpuState(NULL),
fStackTrace(NULL) fStackTrace(NULL)
@@ -32,6 +33,8 @@ Thread::~Thread()
fCpuState->ReleaseReference(); fCpuState->ReleaseReference();
if (fStackTrace != NULL) if (fStackTrace != NULL)
fStackTrace->ReleaseReference(); fStackTrace->ReleaseReference();
if (fSubroutineState != NULL)
fSubroutineState->ReleaseReference();
} }
@@ -121,3 +124,13 @@ Thread::SetExecutedSubroutine(target_addr_t address)
fSubroutineAddress = address; fSubroutineAddress = address;
} }
void
Thread::SetSubroutineCpuState(CpuState* state)
{
if (fSubroutineState != NULL)
fSubroutineState->ReleaseReference();
fSubroutineState = state;
fSubroutineState->AcquireReference();
}
+4
View File
@@ -74,6 +74,9 @@ public:
target_addr_t SubroutineAddress() const target_addr_t SubroutineAddress() const
{ return fSubroutineAddress; } { return fSubroutineAddress; }
void SetExecutedSubroutine(target_addr_t address); void SetExecutedSubroutine(target_addr_t address);
CpuState* SubroutineCpuState() const
{ return fSubroutineState; }
void SetSubroutineCpuState(CpuState* state);
private: private:
Team* fTeam; Team* fTeam;
@@ -82,6 +85,7 @@ private:
uint32 fState; uint32 fState;
bool fExecutedSubroutine; bool fExecutedSubroutine;
target_addr_t fSubroutineAddress; target_addr_t fSubroutineAddress;
CpuState* fSubroutineState;
uint32 fStoppedReason; uint32 fStoppedReason;
BString fStoppedReasonInfo; BString fStoppedReasonInfo;
CpuState* fCpuState; CpuState* fCpuState;