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:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user