hrev45419 adds 2 changesets to branch 'master' old head: 5a6b854033916abf2f924f11d6ce8d52c14153bd new head: 76ed6d72a535697c54305bc36c946e13dc5ed28c overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=76ed6d7+%5E5a6b854 ---------------------------------------------------------------------------- 3fa4297: Add ReturnValueInfo class for storing function return information. 76ed6d7: 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. [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- 14 files changed, 253 insertions(+), 141 deletions(-) src/apps/debugger/Jamfile | 3 +- src/apps/debugger/arch/Architecture.cpp | 12 +- src/apps/debugger/arch/Architecture.h | 4 +- src/apps/debugger/controllers/ThreadHandler.cpp | 48 ++++-- .../debug_info/DebuggerImageDebugInfo.cpp | 5 +- .../debugger/debug_info/DebuggerImageDebugInfo.h | 3 +- .../debugger/debug_info/DwarfImageDebugInfo.cpp | 167 ++++++++++--------- .../debugger/debug_info/DwarfImageDebugInfo.h | 8 +- .../debugger/debug_info/SpecificImageDebugInfo.h | 4 +- src/apps/debugger/jobs/GetStackTraceJob.cpp | 4 +- src/apps/debugger/model/ReturnValueInfo.cpp | 47 ++++++ src/apps/debugger/model/ReturnValueInfo.h | 38 +++++ src/apps/debugger/model/Thread.cpp | 33 ++-- src/apps/debugger/model/Thread.h | 18 +- ############################################################################ Commit: 3fa429781c54a21dd23f1ac128b4e2b79b7e1b82 URL: http://cgit.haiku-os.org/haiku/commit/?id=3fa4297 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Thu Mar 28 03:27:03 2013 UTC Add ReturnValueInfo class for storing function return information. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/model/ReturnValueInfo.cpp b/src/apps/debugger/model/ReturnValueInfo.cpp new file mode 100644 index 0000000..e44da35 --- /dev/null +++ b/src/apps/debugger/model/ReturnValueInfo.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx. + * Distributed under the terms of the MIT License. + */ + +#include "ReturnValueInfo.h" + +#include "CpuState.h" + + +ReturnValueInfo::ReturnValueInfo() + : + BReferenceable(), + fAddress(0), + fState(NULL) +{ +} + + +ReturnValueInfo::ReturnValueInfo(target_addr_t address, CpuState* state) + : + BReferenceable(), + fAddress(address), + fState(state) +{ + state->AcquireReference(); +} + + +ReturnValueInfo::~ReturnValueInfo() +{ + if (fState != NULL) + fState->ReleaseReference(); +} + + +void +ReturnValueInfo::SetTo(target_addr_t address, CpuState* state) +{ + fAddress = address; + + if (fState != NULL) + fState->ReleaseReference(); + + fState = state; + fState->AcquireReference(); +} diff --git a/src/apps/debugger/model/ReturnValueInfo.h b/src/apps/debugger/model/ReturnValueInfo.h new file mode 100644 index 0000000..693da13 --- /dev/null +++ b/src/apps/debugger/model/ReturnValueInfo.h @@ -0,0 +1,38 @@ +/* + * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx. + * Distributed under the terms of the MIT License. + */ +#ifndef RETURN_VALUE_INFO_H +#define RETURN_VALUE_INFO_H + +#include "ObjectList.h" +#include "Referenceable.h" +#include "Types.h" + + +class CpuState; + + +class ReturnValueInfo : public BReferenceable { +public: + ReturnValueInfo(); + ReturnValueInfo(target_addr_t address, + CpuState* state); + ~ReturnValueInfo(); + + void SetTo(target_addr_t address, CpuState* state); + + target_addr_t SubroutineAddress() const + { return fAddress; } + CpuState* State() const { return fState; } + +private: + target_addr_t fAddress; + CpuState* fState; +}; + + +typedef BObjectList<ReturnValueInfo> ReturnValueInfoList; + + +#endif // RETURN_VALUE_INFO_H ############################################################################ Revision: hrev45419 Commit: 76ed6d72a535697c54305bc36c946e13dc5ed28c URL: http://cgit.haiku-os.org/haiku/commit/?id=76ed6d7 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Thu Mar 28 03:21:42 2013 UTC 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. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index c2aaa66..053121c 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -144,6 +144,7 @@ Application Debugger : FileSourceCode.cpp Image.cpp ImageInfo.cpp + ReturnValueInfo.cpp SourceCode.cpp StackFrame.cpp StackFrameValues.cpp @@ -151,7 +152,6 @@ Application Debugger : StackTrace.cpp Statement.cpp SymbolInfo.cpp - UserBreakpoint.cpp Team.cpp TeamMemory.cpp TeamMemoryBlock.cpp @@ -161,6 +161,7 @@ Application Debugger : Type.cpp TypeComponentPath.cpp TypeLookupConstraints.cpp + UserBreakpoint.cpp Variable.cpp Watchpoint.cpp diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index ecae506..1620024 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -94,9 +94,8 @@ Architecture::InitRegisterRules(CfaContext& context) const status_t Architecture::CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, - StackTrace*& _stackTrace, target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, int32 maxStackDepth, bool useExistingTrace, - bool getFullFrameInfo) + StackTrace*& _stackTrace, ReturnValueInfoList* returnValueInfos, + int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo) { BReference<CpuState> cpuStateReference(cpuState); @@ -164,8 +163,8 @@ Architecture::CreateStackTrace(Team* team, if (function != NULL) { status_t error = functionDebugInfo->GetSpecificImageDebugInfo() ->CreateFrame(image, function, cpuState, getFullFrameInfo, - nextFrame == NULL ? returnFunctionAddress : 0, - nextFrame == NULL ? returnFunctionState : 0, frame, + nextFrame == NULL + ? returnValueInfos : NULL, frame, previousCpuState); if (error != B_OK && error != B_UNSUPPORTED) break; @@ -174,8 +173,7 @@ Architecture::CreateStackTrace(Team* team, // If we have no frame yet, let the architecture create it. if (frame == NULL) { status_t error = CreateStackFrame(image, functionDebugInfo, - cpuState, nextFrame == NULL, frame, - previousCpuState); + cpuState, nextFrame == NULL, frame, previousCpuState); if (error != B_OK) break; } diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index e390774..76d553b 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -13,6 +13,7 @@ #include <Referenceable.h> #include <Variant.h> +#include "ReturnValueInfo.h" #include "Types.h" @@ -110,8 +111,7 @@ public: ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, StackTrace*& _stackTrace, - target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, + ReturnValueInfoList* returnValueInfos, int32 maxStackDepth = -1, bool useExistingTrace = false, bool getFullFrameInfo = true); diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index af647cb..b40aa35 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, 0, NULL, 1, + fThread->GetTeam(), this, cpuState, stackTrace, NULL, 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } @@ -484,11 +484,20 @@ ThreadHandler::_DoStepOver(CpuState* cpuState) TRACE_CONTROL(" subroutine call -- installing breakpoint at address " "%#" B_PRIx64 "\n", info.Address() + info.Size()); - fThread->SetExecutedSubroutine(info.TargetAddress()); - fThread->SetSubroutineCpuState(cpuState); if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK) 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()); return true; } @@ -567,8 +576,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, 0, - NULL, 1, false, false) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, NULL, + 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } } @@ -608,8 +617,16 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState) { // That's the return address, so we're done in theory, // unless we're a recursive function. Check if we've actually - // exited the previous stack frame or not. - fThread->SetExecutedSubroutine(cpuState->InstructionPointer()); + // exited the previous stack frame or not + 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(); bool hasExitedFrame = fDebuggerInterface->GetArchitecture() ->StackGrowthDirection() == STACK_GROWTH_DIRECTION_POSITIVE @@ -654,8 +671,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, 0, - NULL, 1, false, false) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, NULL, + 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } } @@ -686,7 +703,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) BReference<StackTrace> stackTraceReference(stackTrace); if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, 0, + fThread->GetTeam(), this, cpuState, stackTrace, NULL, 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } @@ -694,8 +711,15 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) if (stackTrace != NULL && stackTrace->FrameAt(0) ->FrameAddress() != fPreviousFrameAddress) { - 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(); } return false; diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp index c7a77e1..8aa49b4 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp @@ -68,9 +68,8 @@ DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t address) status_t DebuggerImageDebugInfo::CreateFrame(Image* image, FunctionInstance* functionInstance, CpuState* cpuState, - bool getFullFrameInfo, target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, StackFrame*& _previousFrame, - CpuState*& _previousCpuState) + bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos, + StackFrame*& _previousFrame, CpuState*& _previousCpuState) { return B_UNSUPPORTED; } diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h index 91d0c1b..efe5816 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h @@ -36,8 +36,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, + ReturnValueInfoList* returnValueInfos, StackFrame*& _previousFrame, CpuState*& _previousCpuState); virtual status_t GetStatement(FunctionDebugInfo* function, diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 5c58ed3..b467cd1 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -522,9 +522,8 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address) status_t DwarfImageDebugInfo::CreateFrame(Image* image, FunctionInstance* functionInstance, CpuState* cpuState, - bool getFullFrameInfo, target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, StackFrame*& _frame, - CpuState*& _previousCpuState) + bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos, + StackFrame*& _frame, CpuState*& _previousCpuState) { DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>( functionInstance->GetFunctionDebugInfo()); @@ -674,9 +673,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image, instructionPointer, functionInstance->Address() - fRelocationDelta, subprogramEntry->Variables(), subprogramEntry->Blocks()); - if (returnFunctionAddress != 0) { - _CreateReturnValue(returnFunctionAddress, returnFunctionState, - image, frame, *stackFrameDebugInfo); + if (!returnValueInfos->IsEmpty()) { + _CreateReturnValues(returnValueInfos, image, frame, + *stackFrameDebugInfo); } } @@ -1087,88 +1086,94 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit, status_t -DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, Image* image, StackFrame* frame, - DwarfStackFrameDebugInfo& factory) +DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos, + Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory) { - if (!image->ContainsAddress(returnFunctionAddress)) { - // our current image doesn't contain the target function, - // locate the one which does. - image = image->GetTeam()->ImageByAddress(returnFunctionAddress); - if (image == NULL) - return B_BAD_VALUE; - } - - status_t result = B_OK; - ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); - FunctionInstance* targetFunction; - 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; + for (int32 i = 0; i < returnValueInfos->CountItems(); i++) { + ReturnValueInfo* valueInfo = returnValueInfos->ItemAt(i); + target_addr_t subroutineAddress = valueInfo->SubroutineAddress(); + CpuState* subroutineState = valueInfo->State(); + if (!image->ContainsAddress(subroutineAddress)) { + // our current image doesn't contain the target function, + // locate the one which does. + image = image->GetTeam()->ImageByAddress(subroutineAddress); + if (image == NULL) { + // nothing we can do, try the next entry (if any) + continue; + } } - target_size_t addressSize = fDebuggerInterface->GetArchitecture() - ->AddressSize(); - ssize_t bytesRead = fDebuggerInterface->ReadMemory(info.TargetAddress(), - &returnFunctionAddress, addressSize); + status_t result = B_OK; + ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); + FunctionInstance* targetFunction; + if (subroutineAddress >= fPLTSectionStart + && subroutineAddress < 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( + subroutineAddress, info, subroutineState) != B_OK) { + return B_BAD_VALUE; + } - if (bytesRead != (ssize_t)addressSize) - return B_BAD_VALUE; - } + target_size_t addressSize = fDebuggerInterface->GetArchitecture() + ->AddressSize(); + ssize_t bytesRead = fDebuggerInterface->ReadMemory( + info.TargetAddress(), &subroutineAddress, addressSize); + if (bytesRead != (ssize_t)addressSize) + return B_BAD_VALUE; + } - targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress); - if (targetFunction != NULL) { - DwarfFunctionDebugInfo* targetInfo = - 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; - } + targetFunction = imageInfo->FunctionAtAddress(subroutineAddress); + if (targetFunction != NULL) { + DwarfFunctionDebugInfo* targetInfo = + 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; - 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; + 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; + } } } diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index 7dab0fb..422925a 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -64,8 +64,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, + ReturnValueInfoList* returnValueInfos, StackFrame*& _frame, CpuState*& _previousCpuState); virtual status_t GetStatement(FunctionDebugInfo* function, @@ -105,9 +104,8 @@ private: const EntryListWrapper& variableEntries, const EntryListWrapper& blockEntries); - status_t _CreateReturnValue( - target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, + status_t _CreateReturnValues( + ReturnValueInfoList* returnValueInfos, Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory); diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h index 595d238..02a1fa9 100644 --- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h +++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h @@ -10,6 +10,7 @@ #include <Referenceable.h> #include "AddressSectionTypes.h" +#include "ReturnValueInfo.h" #include "Types.h" @@ -56,8 +57,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - target_addr_t returnFunctionAddress, - CpuState* returnFunctionState, + ReturnValueInfoList* returnValueInfos, StackFrame*& _Frame, CpuState*& _previousCpuState) = 0; // returns reference to previous frame diff --git a/src/apps/debugger/jobs/GetStackTraceJob.cpp b/src/apps/debugger/jobs/GetStackTraceJob.cpp index c3a2316..0bc286e 100644 --- a/src/apps/debugger/jobs/GetStackTraceJob.cpp +++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp @@ -58,9 +58,7 @@ GetStackTraceJob::Do() // get the stack trace StackTrace* stackTrace; status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this, - fCpuState, stackTrace, fThread->ExecutedSubroutine() - ? fThread->SubroutineAddress() : 0, fThread->ExecutedSubroutine() - ? fThread->SubroutineCpuState() : NULL); + fCpuState, stackTrace, fThread->ReturnValueInfos()); if (error != B_OK) return error; BReference<StackTrace> stackTraceReference(stackTrace, true); diff --git a/src/apps/debugger/model/Thread.cpp b/src/apps/debugger/model/Thread.cpp index e32424c..0dc319f 100644 --- a/src/apps/debugger/model/Thread.cpp +++ b/src/apps/debugger/model/Thread.cpp @@ -18,8 +18,7 @@ Thread::Thread(Team* team, thread_id threadID) fID(threadID), fState(THREAD_STATE_UNKNOWN), fExecutedSubroutine(false), - fSubroutineAddress(0), - fSubroutineState(NULL), + fReturnValueInfos(NULL), fStoppedReason(THREAD_STOPPED_UNKNOWN), fCpuState(NULL), fStackTrace(NULL) @@ -33,14 +32,19 @@ Thread::~Thread() fCpuState->ReleaseReference(); if (fStackTrace != NULL) fStackTrace->ReleaseReference(); - if (fSubroutineState != NULL) - fSubroutineState->ReleaseReference(); + + ClearReturnValueInfos(); + delete fReturnValueInfos; } status_t Thread::Init() { + fReturnValueInfos = new(std::nothrow) ReturnValueInfoList; + if (fReturnValueInfos == NULL) + return B_NO_MEMORY; + return B_OK; } @@ -74,7 +78,7 @@ Thread::SetState(uint32 state, uint32 reason, const BString& info) SetCpuState(NULL); SetStackTrace(NULL); fExecutedSubroutine = false; - fSubroutineAddress = 0; + ClearReturnValueInfos(); } fTeam->NotifyThreadStateChanged(this); @@ -117,20 +121,23 @@ Thread::SetStackTrace(StackTrace* trace) } -void -Thread::SetExecutedSubroutine(target_addr_t address) +status_t +Thread::AddReturnValueInfo(ReturnValueInfo* info) { + if (!fReturnValueInfos->AddItem(info)) + return B_NO_MEMORY; + + info->AcquireReference(); fExecutedSubroutine = true; - fSubroutineAddress = address; + return B_OK; } void -Thread::SetSubroutineCpuState(CpuState* state) +Thread::ClearReturnValueInfos() { - if (fSubroutineState != NULL) - fSubroutineState->ReleaseReference(); + for (int32 i = 0; i < fReturnValueInfos->CountItems(); i++) + fReturnValueInfos->ItemAt(i)->ReleaseReference(); - fSubroutineState = state; - fSubroutineState->AcquireReference(); + fReturnValueInfos->MakeEmpty(); } diff --git a/src/apps/debugger/model/Thread.h b/src/apps/debugger/model/Thread.h index 17aa330..e25a6c7 100644 --- a/src/apps/debugger/model/Thread.h +++ b/src/apps/debugger/model/Thread.h @@ -11,6 +11,7 @@ #include <Referenceable.h> #include <util/DoublyLinkedList.h> +#include "ReturnValueInfo.h" #include "types/Types.h" @@ -69,14 +70,11 @@ public: StackTrace* GetStackTrace() const { return fStackTrace; } void SetStackTrace(StackTrace* trace); - bool ExecutedSubroutine() const - { return fExecutedSubroutine; } - target_addr_t SubroutineAddress() const - { return fSubroutineAddress; } - void SetExecutedSubroutine(target_addr_t address); - CpuState* SubroutineCpuState() const - { return fSubroutineState; } - void SetSubroutineCpuState(CpuState* state); + ReturnValueInfoList* + ReturnValueInfos() const + { return fReturnValueInfos; } + status_t AddReturnValueInfo(ReturnValueInfo* info); + void ClearReturnValueInfos(); private: Team* fTeam; @@ -84,8 +82,8 @@ private: BString fName; uint32 fState; bool fExecutedSubroutine; - target_addr_t fSubroutineAddress; - CpuState* fSubroutineState; + ReturnValueInfoList* + fReturnValueInfos; uint32 fStoppedReason; BString fStoppedReasonInfo; CpuState* fCpuState;