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:44:54 -04:00
parent 04c919f9d6
commit 029fcc4ad6
11 changed files with 41 additions and 12 deletions

View File

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

View File

@ -111,6 +111,7 @@ public:
CpuState* cpuState,
StackTrace*& _stackTrace,
target_addr_t returnFunctionAddress,
CpuState* returnFunctionState,
int32 maxStackDepth = -1,
bool useExistingTrace = false,
bool getFullFrameInfo = true);

View File

@ -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);
}
}

View File

@ -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;
}

View File

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

View File

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

View File

@ -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);

View File

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

View File

@ -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);

View File

@ -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();
}

View File

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