diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index e37ff70840..4041bfe369 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -46,6 +46,7 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, fNodeManager(NULL), fListener(listener), fWaitingNode(NULL), + fCurrentBlock(NULL), fTraceWaitingThread(NULL) { fTeam->AddListener(this); @@ -61,6 +62,9 @@ DebugReportGenerator::~DebugReportGenerator() fNodeManager->RemoveListener(this); fNodeManager->ReleaseReference(); } + + if (fCurrentBlock != NULL) + fCurrentBlock->ReleaseReference(); } @@ -161,6 +165,19 @@ DebugReportGenerator::ThreadStackTraceChanged(const ::Team::ThreadEvent& event) } +void +DebugReportGenerator::MemoryBlockRetrieved(TeamMemoryBlock* block) +{ + if (fCurrentBlock != NULL) { + fCurrentBlock->ReleaseReference(); + fCurrentBlock = NULL; + } + + fCurrentBlock = block; + release_sem(fTeamDataSem); +} + + void DebugReportGenerator::ValueNodeValueChanged(ValueNode* node) { @@ -323,6 +340,9 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, _output << data; if (frame->CountParameters() == 0 && frame->CountLocalVariables() == 0) { + // only dump the topmost frame + if (i == 0) + _DumpStackFrameMemory(_output, thread->GetCpuState()); continue; } @@ -362,6 +382,24 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, } +void +DebugReportGenerator::_DumpStackFrameMemory(BString& _output, + CpuState* state) +{ + target_addr_t address = state->StackPointer(); + if (fCurrentBlock == NULL || !fCurrentBlock->Contains(address)) { + fListener->InspectRequested(address, this); + status_t result = B_OK; + do { + result = acquire_sem(fTeamDataSem); + } while (result == B_INTERRUPTED); + } + _output << "\t\t\tFrame memory:\n"; + UiUtils::DumpMemory(_output, 3, fCurrentBlock, address, 1, 16, + fCurrentBlock->BaseAddress() + fCurrentBlock->Size() - address); +} + + status_t DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame, int32 maxDepth) @@ -371,7 +409,9 @@ DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame, fWaitingNode = node; fListener->ValueNodeValueRequested(frame->GetCpuState(), fNodeManager->GetContainer(), node); - result = acquire_sem(fTeamDataSem); + do { + result = acquire_sem(fTeamDataSem); + } while (result == B_INTERRUPTED); } if (node->LocationAndValueResolutionState() == B_OK && maxDepth > 0) { diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 01ae75ece0..56bf8a4a7c 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -9,6 +9,7 @@ #include #include "Team.h" +#include "TeamMemoryBlock.h" #include "ValueNodeContainer.h" @@ -26,7 +27,7 @@ class ValueNodeManager; class DebugReportGenerator : public BLooper, private Team::Listener, - private ValueNodeContainer::Listener { + private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { public: DebugReportGenerator(::Team* team, UserInterfaceListener* listener); @@ -39,18 +40,27 @@ public: virtual void MessageReceived(BMessage* message); +private: + // Team::Listener virtual void ThreadStackTraceChanged( const Team::ThreadEvent& event); + // TeamMemoryBlock::Listener + virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); + + // ValueNodeContainer::Listener virtual void ValueNodeValueChanged(ValueNode* node); + private: status_t _GenerateReport(const entry_ref& outputPath); - status_t _GenerateReportHeader(BString& output); - status_t _DumpLoadedImages(BString& output); - status_t _DumpRunningThreads(BString& output); - status_t _DumpDebuggedThreadInfo(BString& output, + status_t _GenerateReportHeader(BString& _output); + status_t _DumpLoadedImages(BString& _output); + status_t _DumpRunningThreads(BString& _output); + status_t _DumpDebuggedThreadInfo(BString& _output, ::Thread* thread); + void _DumpStackFrameMemory(BString& _output, + CpuState* state); status_t _ResolveValueIfNeeded(ValueNode* node, StackFrame* frame, int32 maxDepth); @@ -62,6 +72,7 @@ private: ValueNodeManager* fNodeManager; UserInterfaceListener* fListener; ValueNode* fWaitingNode; + TeamMemoryBlock* fCurrentBlock; ::Thread* fTraceWaitingThread; };