Refactoring to handle multiple return values.

- Replace use of address + CpuState pair in Thread,
  SpecificImageDebugInfo::CreateStackTrace() with a ReturnValueInfoList.
  Adjust all implementing subclasses and callers accordingly.

- DwarfImageDebugInfo::CreateReturnValue() -> CreateReturnValues().
  Now processes a list of return value information structures rather
  than just a single one. This means we can now handle multiple return
  values in a single statement. This still isn't entirely correct though,
  since, e.g. for functions whose return types fit in a register we need
  to either retrieve them immediately after function return, or store the
  CPU state at that point in time for later use in value retrieval,
  otherwise the return values will all be those of the last called function.
This commit is contained in:
Rene Gollent
2013-03-27 23:27:49 -04:00
parent 3fa429781c
commit 76ed6d72a5
12 changed files with 167 additions and 140 deletions
+2 -1
View File
@@ -144,6 +144,7 @@ Application Debugger :
FileSourceCode.cpp FileSourceCode.cpp
Image.cpp Image.cpp
ImageInfo.cpp ImageInfo.cpp
ReturnValueInfo.cpp
SourceCode.cpp SourceCode.cpp
StackFrame.cpp StackFrame.cpp
StackFrameValues.cpp StackFrameValues.cpp
@@ -151,7 +152,6 @@ Application Debugger :
StackTrace.cpp StackTrace.cpp
Statement.cpp Statement.cpp
SymbolInfo.cpp SymbolInfo.cpp
UserBreakpoint.cpp
Team.cpp Team.cpp
TeamMemory.cpp TeamMemory.cpp
TeamMemoryBlock.cpp TeamMemoryBlock.cpp
@@ -161,6 +161,7 @@ Application Debugger :
Type.cpp Type.cpp
TypeComponentPath.cpp TypeComponentPath.cpp
TypeLookupConstraints.cpp TypeLookupConstraints.cpp
UserBreakpoint.cpp
Variable.cpp Variable.cpp
Watchpoint.cpp Watchpoint.cpp
+5 -7
View File
@@ -94,9 +94,8 @@ Architecture::InitRegisterRules(CfaContext& context) const
status_t 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, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState, int32 maxStackDepth, bool useExistingTrace, int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo)
bool getFullFrameInfo)
{ {
BReference<CpuState> cpuStateReference(cpuState); BReference<CpuState> cpuStateReference(cpuState);
@@ -164,8 +163,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, nextFrame == NULL
nextFrame == NULL ? returnFunctionState : 0, frame, ? returnValueInfos : NULL, frame,
previousCpuState); previousCpuState);
if (error != B_OK && error != B_UNSUPPORTED) if (error != B_OK && error != B_UNSUPPORTED)
break; break;
@@ -174,8 +173,7 @@ Architecture::CreateStackTrace(Team* team,
// If we have no frame yet, let the architecture create it. // If we have no frame yet, let the architecture create it.
if (frame == NULL) { if (frame == NULL) {
status_t error = CreateStackFrame(image, functionDebugInfo, status_t error = CreateStackFrame(image, functionDebugInfo,
cpuState, nextFrame == NULL, frame, cpuState, nextFrame == NULL, frame, previousCpuState);
previousCpuState);
if (error != B_OK) if (error != B_OK)
break; break;
} }
+2 -2
View File
@@ -13,6 +13,7 @@
#include <Referenceable.h> #include <Referenceable.h>
#include <Variant.h> #include <Variant.h>
#include "ReturnValueInfo.h"
#include "Types.h" #include "Types.h"
@@ -110,8 +111,7 @@ public:
ImageDebugInfoProvider* imageInfoProvider, ImageDebugInfoProvider* imageInfoProvider,
CpuState* cpuState, CpuState* cpuState,
StackTrace*& _stackTrace, StackTrace*& _stackTrace,
target_addr_t returnFunctionAddress, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState,
int32 maxStackDepth = -1, int32 maxStackDepth = -1,
bool useExistingTrace = false, bool useExistingTrace = false,
bool getFullFrameInfo = true); bool getFullFrameInfo = true);
+36 -12
View File
@@ -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, NULL, 1, fThread->GetTeam(), this, cpuState, stackTrace, NULL, 1,
false, false) == B_OK) { false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
@@ -484,11 +484,20 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
TRACE_CONTROL(" subroutine call -- installing breakpoint at address " TRACE_CONTROL(" subroutine call -- installing breakpoint at address "
"%#" B_PRIx64 "\n", info.Address() + info.Size()); "%#" B_PRIx64 "\n", info.Address() + info.Size());
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;
ReturnValueInfo* returnInfo = new(std::nothrow) ReturnValueInfo(
info.TargetAddress(), cpuState);
if (returnInfo == NULL)
return false;
BReference<ReturnValueInfo> returnInfoReference(returnInfo, true);
if (fThread->AddReturnValueInfo(returnInfo) != B_OK)
return false;
returnInfoReference.Detach();
_RunThread(cpuState->InstructionPointer()); _RunThread(cpuState->InstructionPointer());
return true; return true;
} }
@@ -567,8 +576,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, fThread->GetTeam(), this, cpuState, stackTrace, NULL,
NULL, 1, false, false) == B_OK) { 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
} }
@@ -608,8 +617,16 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
{ {
// That's the return address, so we're done in theory, // That's the return address, so we're done in theory,
// unless we're a recursive function. Check if we've actually // unless we're a recursive function. Check if we've actually
// exited the previous stack frame or not. // exited the previous stack frame or not
fThread->SetExecutedSubroutine(cpuState->InstructionPointer()); ReturnValueInfo* info = new(std::nothrow) ReturnValueInfo(
cpuState->InstructionPointer(), cpuState);
if (info == NULL)
return false;
BReference<ReturnValueInfo> infoReference(info, true);
if (fThread->AddReturnValueInfo(info) != B_OK)
return false;
infoReference.Detach();
target_addr_t framePointer = cpuState->StackFramePointer(); target_addr_t framePointer = cpuState->StackFramePointer();
bool hasExitedFrame = fDebuggerInterface->GetArchitecture() bool hasExitedFrame = fDebuggerInterface->GetArchitecture()
->StackGrowthDirection() == STACK_GROWTH_DIRECTION_POSITIVE ->StackGrowthDirection() == STACK_GROWTH_DIRECTION_POSITIVE
@@ -654,8 +671,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, fThread->GetTeam(), this, cpuState, stackTrace, NULL,
NULL, 1, false, false) == B_OK) { 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
} }
@@ -686,7 +703,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
BReference<StackTrace> stackTraceReference(stackTrace); BReference<StackTrace> stackTraceReference(stackTrace);
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,
NULL, 1, false, false) == B_OK) { NULL, 1, false, false) == B_OK) {
stackTraceReference.SetTo(stackTrace, true); stackTraceReference.SetTo(stackTrace, true);
} }
@@ -694,8 +711,15 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
if (stackTrace != NULL && stackTrace->FrameAt(0) if (stackTrace != NULL && stackTrace->FrameAt(0)
->FrameAddress() != fPreviousFrameAddress) { ->FrameAddress() != fPreviousFrameAddress) {
fThread->SetExecutedSubroutine( ReturnValueInfo* info = new(std::nothrow) ReturnValueInfo(
cpuState->InstructionPointer()); cpuState->InstructionPointer(), cpuState);
if (info == NULL)
return false;
BReference<ReturnValueInfo> infoReference(info, true);
if (fThread->AddReturnValueInfo(info) != B_OK)
return false;
infoReference.Detach();
} }
return false; return false;
@@ -68,9 +68,8 @@ DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t address)
status_t 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, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState, StackFrame*& _previousFrame, StackFrame*& _previousFrame, CpuState*& _previousCpuState)
CpuState*& _previousCpuState)
{ {
return B_UNSUPPORTED; return B_UNSUPPORTED;
} }
@@ -36,8 +36,7 @@ public:
FunctionInstance* functionInstance, FunctionInstance* functionInstance,
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState,
StackFrame*& _previousFrame, StackFrame*& _previousFrame,
CpuState*& _previousCpuState); CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function, virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -522,9 +522,8 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address)
status_t 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, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState, StackFrame*& _frame, StackFrame*& _frame, CpuState*& _previousCpuState)
CpuState*& _previousCpuState)
{ {
DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>( DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
functionInstance->GetFunctionDebugInfo()); functionInstance->GetFunctionDebugInfo());
@@ -674,9 +673,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
instructionPointer, functionInstance->Address() - fRelocationDelta, instructionPointer, functionInstance->Address() - fRelocationDelta,
subprogramEntry->Variables(), subprogramEntry->Blocks()); subprogramEntry->Variables(), subprogramEntry->Blocks());
if (returnFunctionAddress != 0) { if (!returnValueInfos->IsEmpty()) {
_CreateReturnValue(returnFunctionAddress, returnFunctionState, _CreateReturnValues(returnValueInfos, image, frame,
image, frame, *stackFrameDebugInfo); *stackFrameDebugInfo);
} }
} }
@@ -1087,88 +1086,94 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
status_t status_t
DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress, DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState, Image* image, StackFrame* frame, Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory)
DwarfStackFrameDebugInfo& factory)
{ {
if (!image->ContainsAddress(returnFunctionAddress)) { for (int32 i = 0; i < returnValueInfos->CountItems(); i++) {
// our current image doesn't contain the target function, ReturnValueInfo* valueInfo = returnValueInfos->ItemAt(i);
// locate the one which does. target_addr_t subroutineAddress = valueInfo->SubroutineAddress();
image = image->GetTeam()->ImageByAddress(returnFunctionAddress); CpuState* subroutineState = valueInfo->State();
if (image == NULL) if (!image->ContainsAddress(subroutineAddress)) {
return B_BAD_VALUE; // our current image doesn't contain the target function,
} // locate the one which does.
image = image->GetTeam()->ImageByAddress(subroutineAddress);
status_t result = B_OK; if (image == NULL) {
ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); // nothing we can do, try the next entry (if any)
FunctionInstance* targetFunction; continue;
if (returnFunctionAddress >= fPLTSectionStart }
&& returnFunctionAddress < fPLTSectionEnd) {
// if the function in question is position-independent, the call
// will actually have taken us to its corresponding PLT slot.
// in such a case, look at the disassembled jump to determine
// where to find the actual function address.
InstructionInfo info;
if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
returnFunctionAddress, info, returnFunctionState) != B_OK) {
return B_BAD_VALUE;
} }
target_size_t addressSize = fDebuggerInterface->GetArchitecture() status_t result = B_OK;
->AddressSize(); ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
ssize_t bytesRead = fDebuggerInterface->ReadMemory(info.TargetAddress(), FunctionInstance* targetFunction;
&returnFunctionAddress, addressSize); if (subroutineAddress >= fPLTSectionStart
&& subroutineAddress < fPLTSectionEnd) {
if (bytesRead != (ssize_t)addressSize) // if the function in question is position-independent, the call
return B_BAD_VALUE; // will actually have taken us to its corresponding PLT slot.
} // in such a case, look at the disassembled jump to determine
// where to find the actual function address.
InstructionInfo info;
targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress); if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
if (targetFunction != NULL) { subroutineAddress, info, subroutineState) != B_OK) {
DwarfFunctionDebugInfo* targetInfo = return B_BAD_VALUE;
dynamic_cast<DwarfFunctionDebugInfo*>(
targetFunction->GetFunctionDebugInfo());
if (targetInfo != NULL) {
DIESubprogram* subProgram = targetInfo->SubprogramEntry();
DIEType* returnType = subProgram->ReturnType();
if (returnType == NULL) {
// check if we have a specification, and if so, if that has
// a return type
subProgram = dynamic_cast<DIESubprogram*>(subProgram->Specification());
if (subProgram != NULL)
returnType = subProgram->ReturnType();
// function doesn't return a value, we're done.
if (returnType == NULL)
return B_OK;
} }
uint32 byteSize = 0; target_size_t addressSize = fDebuggerInterface->GetArchitecture()
if (returnType->ByteSize() == NULL) { ->AddressSize();
if (dynamic_cast<DIEAddressingType*>(returnType) != NULL) ssize_t bytesRead = fDebuggerInterface->ReadMemory(
byteSize = fArchitecture->AddressSize(); info.TargetAddress(), &subroutineAddress, addressSize);
} else
byteSize = returnType->ByteSize()->constant;
ValueLocation* location; if (bytesRead != (ssize_t)addressSize)
result = fArchitecture->GetReturnAddressLocation(frame, return B_BAD_VALUE;
byteSize, location); }
if (result != B_OK)
return result;
BReference<ValueLocation> locationReference(location, true); targetFunction = imageInfo->FunctionAtAddress(subroutineAddress);
Variable* variable = NULL; if (targetFunction != NULL) {
BReference<FunctionID> idReference( DwarfFunctionDebugInfo* targetInfo =
targetFunction->GetFunctionID(), true); dynamic_cast<DwarfFunctionDebugInfo*>(
result = factory.CreateReturnValue(idReference, returnType, targetFunction->GetFunctionDebugInfo());
location, variable); if (targetInfo != NULL) {
if (result != B_OK) DIESubprogram* subProgram = targetInfo->SubprogramEntry();
return result; DIEType* returnType = subProgram->ReturnType();
if (returnType == NULL) {
// check if we have a specification, and if so, if that has
// a return type
subProgram = dynamic_cast<DIESubprogram*>(
subProgram->Specification());
if (subProgram != NULL)
returnType = subProgram->ReturnType();
BReference<Variable> variableReference(variable, true); // function doesn't return a value, we're done.
if (!frame->AddLocalVariable(variable)) if (returnType == NULL)
return B_NO_MEMORY; return B_OK;
}
uint32 byteSize = 0;
if (returnType->ByteSize() == NULL) {
if (dynamic_cast<DIEAddressingType*>(returnType) != NULL)
byteSize = fArchitecture->AddressSize();
} else
byteSize = returnType->ByteSize()->constant;
ValueLocation* location;
result = fArchitecture->GetReturnAddressLocation(frame,
byteSize, location);
if (result != B_OK)
return result;
BReference<ValueLocation> locationReference(location, true);
Variable* variable = NULL;
BReference<FunctionID> idReference(
targetFunction->GetFunctionID(), true);
result = factory.CreateReturnValue(idReference, returnType,
location, variable);
if (result != B_OK)
return result;
BReference<Variable> variableReference(variable, true);
if (!frame->AddLocalVariable(variable))
return B_NO_MEMORY;
}
} }
} }
@@ -64,8 +64,7 @@ public:
FunctionInstance* functionInstance, FunctionInstance* functionInstance,
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState,
StackFrame*& _frame, StackFrame*& _frame,
CpuState*& _previousCpuState); CpuState*& _previousCpuState);
virtual status_t GetStatement(FunctionDebugInfo* function, virtual status_t GetStatement(FunctionDebugInfo* function,
@@ -105,9 +104,8 @@ private:
const EntryListWrapper& variableEntries, const EntryListWrapper& variableEntries,
const EntryListWrapper& blockEntries); const EntryListWrapper& blockEntries);
status_t _CreateReturnValue( status_t _CreateReturnValues(
target_addr_t returnFunctionAddress, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState,
Image* image, Image* image,
StackFrame* frame, StackFrame* frame,
DwarfStackFrameDebugInfo& factory); DwarfStackFrameDebugInfo& factory);
@@ -10,6 +10,7 @@
#include <Referenceable.h> #include <Referenceable.h>
#include "AddressSectionTypes.h" #include "AddressSectionTypes.h"
#include "ReturnValueInfo.h"
#include "Types.h" #include "Types.h"
@@ -56,8 +57,7 @@ public:
FunctionInstance* functionInstance, FunctionInstance* functionInstance,
CpuState* cpuState, CpuState* cpuState,
bool getFullFrameInfo, bool getFullFrameInfo,
target_addr_t returnFunctionAddress, ReturnValueInfoList* returnValueInfos,
CpuState* returnFunctionState,
StackFrame*& _Frame, StackFrame*& _Frame,
CpuState*& _previousCpuState) = 0; CpuState*& _previousCpuState) = 0;
// returns reference to previous frame // returns reference to previous frame
+1 -3
View File
@@ -58,9 +58,7 @@ GetStackTraceJob::Do()
// get the stack trace // get the stack trace
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->ReturnValueInfos());
? 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);
+20 -13
View File
@@ -18,8 +18,7 @@ Thread::Thread(Team* team, thread_id threadID)
fID(threadID), fID(threadID),
fState(THREAD_STATE_UNKNOWN), fState(THREAD_STATE_UNKNOWN),
fExecutedSubroutine(false), fExecutedSubroutine(false),
fSubroutineAddress(0), fReturnValueInfos(NULL),
fSubroutineState(NULL),
fStoppedReason(THREAD_STOPPED_UNKNOWN), fStoppedReason(THREAD_STOPPED_UNKNOWN),
fCpuState(NULL), fCpuState(NULL),
fStackTrace(NULL) fStackTrace(NULL)
@@ -33,14 +32,19 @@ Thread::~Thread()
fCpuState->ReleaseReference(); fCpuState->ReleaseReference();
if (fStackTrace != NULL) if (fStackTrace != NULL)
fStackTrace->ReleaseReference(); fStackTrace->ReleaseReference();
if (fSubroutineState != NULL)
fSubroutineState->ReleaseReference(); ClearReturnValueInfos();
delete fReturnValueInfos;
} }
status_t status_t
Thread::Init() Thread::Init()
{ {
fReturnValueInfos = new(std::nothrow) ReturnValueInfoList;
if (fReturnValueInfos == NULL)
return B_NO_MEMORY;
return B_OK; return B_OK;
} }
@@ -74,7 +78,7 @@ Thread::SetState(uint32 state, uint32 reason, const BString& info)
SetCpuState(NULL); SetCpuState(NULL);
SetStackTrace(NULL); SetStackTrace(NULL);
fExecutedSubroutine = false; fExecutedSubroutine = false;
fSubroutineAddress = 0; ClearReturnValueInfos();
} }
fTeam->NotifyThreadStateChanged(this); fTeam->NotifyThreadStateChanged(this);
@@ -117,20 +121,23 @@ Thread::SetStackTrace(StackTrace* trace)
} }
void status_t
Thread::SetExecutedSubroutine(target_addr_t address) Thread::AddReturnValueInfo(ReturnValueInfo* info)
{ {
if (!fReturnValueInfos->AddItem(info))
return B_NO_MEMORY;
info->AcquireReference();
fExecutedSubroutine = true; fExecutedSubroutine = true;
fSubroutineAddress = address; return B_OK;
} }
void void
Thread::SetSubroutineCpuState(CpuState* state) Thread::ClearReturnValueInfos()
{ {
if (fSubroutineState != NULL) for (int32 i = 0; i < fReturnValueInfos->CountItems(); i++)
fSubroutineState->ReleaseReference(); fReturnValueInfos->ItemAt(i)->ReleaseReference();
fSubroutineState = state; fReturnValueInfos->MakeEmpty();
fSubroutineState->AcquireReference();
} }
+8 -10
View File
@@ -11,6 +11,7 @@
#include <Referenceable.h> #include <Referenceable.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include "ReturnValueInfo.h"
#include "types/Types.h" #include "types/Types.h"
@@ -69,14 +70,11 @@ public:
StackTrace* GetStackTrace() const { return fStackTrace; } StackTrace* GetStackTrace() const { return fStackTrace; }
void SetStackTrace(StackTrace* trace); void SetStackTrace(StackTrace* trace);
bool ExecutedSubroutine() const ReturnValueInfoList*
{ return fExecutedSubroutine; } ReturnValueInfos() const
target_addr_t SubroutineAddress() const { return fReturnValueInfos; }
{ return fSubroutineAddress; } status_t AddReturnValueInfo(ReturnValueInfo* info);
void SetExecutedSubroutine(target_addr_t address); void ClearReturnValueInfos();
CpuState* SubroutineCpuState() const
{ return fSubroutineState; }
void SetSubroutineCpuState(CpuState* state);
private: private:
Team* fTeam; Team* fTeam;
@@ -84,8 +82,8 @@ private:
BString fName; BString fName;
uint32 fState; uint32 fState;
bool fExecutedSubroutine; bool fExecutedSubroutine;
target_addr_t fSubroutineAddress; ReturnValueInfoList*
CpuState* fSubroutineState; fReturnValueInfos;
uint32 fStoppedReason; uint32 fStoppedReason;
BString fStoppedReasonInfo; BString fStoppedReasonInfo;
CpuState* fCpuState; CpuState* fCpuState;