hrev46063 adds 2 changesets to branch 'master' old head: d1d48f6483357fe66a04014eb35408c0af27d225 new head: 396a3d082f8e9535f0482b90731ee7965a266ce0 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=396a3d0+%5Ed1d48f6 ---------------------------------------------------------------------------- 92d6655: Debugger: Implement #9960. - DebugReportGenerator now retrieves and dumps disassembly for the crashing function up to the crashing line. 396a3d0: Merge branch 'debugger_report_add_disassembly' [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- 2 files changed, 92 insertions(+), 4 deletions(-) .../controllers/DebugReportGenerator.cpp | 87 +++++++++++++++++++- .../debugger/controllers/DebugReportGenerator.h | 9 +- ############################################################################ Commit: 92d6655640a788eea5faacbabe1aaed78da7ee11 URL: http://cgit.haiku-os.org/haiku/commit/?id=92d6655 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sun Sep 15 13:32:19 2013 UTC Ticket: https://dev.haiku-os.org/ticket/9960 Debugger: Implement #9960. - DebugReportGenerator now retrieves and dumps disassembly for the crashing function up to the crashing line. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 66ac0f2..60cdba9 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -18,12 +18,15 @@ #include "AreaInfo.h" #include "CpuState.h" #include "DebuggerInterface.h" +#include "DisassembledCode.h" +#include "FunctionInstance.h" #include "Image.h" #include "MessageCodes.h" #include "Register.h" #include "SemaphoreInfo.h" #include "StackFrame.h" #include "StackTrace.h" +#include "Statement.h" #include "StringUtils.h" #include "SystemInfo.h" #include "Team.h" @@ -51,7 +54,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, fWaitingNode(NULL), fCurrentBlock(NULL), fBlockRetrievalStatus(B_OK), - fTraceWaitingThread(NULL) + fTraceWaitingThread(NULL), + fSourceWaitingFunction(NULL) { fTeam->AddListener(this); fArchitecture->AcquireReference(); @@ -204,6 +208,20 @@ DebugReportGenerator::ValueNodeValueChanged(ValueNode* node) } +void +DebugReportGenerator::FunctionSourceCodeChanged(Function* function) +{ + AutoLocker< ::Team> teamLocker(fTeam); + if (function == fSourceWaitingFunction) { + if (function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_LOADED + || function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_UNAVAILABLE) { + release_sem(fTeamDataSem); + } + } +} + status_t DebugReportGenerator::_GenerateReportHeader(BString& _output) { @@ -452,9 +470,12 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, && frame->CountLocalVariables() == 0) { // only dump the topmost frame if (i == 0) { + locker.Unlock(); + _DumpFunctionDisassembly(_output, frame->InstructionPointer()); _DumpStackFrameMemory(_output, thread->GetCpuState(), frame->FrameAddress(), thread->GetTeam()->GetArchitecture() ->StackGrowthDirection()); + locker.Lock(); } continue; } @@ -496,6 +517,66 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, void +DebugReportGenerator::_DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer) +{ + AutoLocker< ::Team> teamLocker(fTeam); + BString data; + FunctionInstance* instance = NULL; + Statement* statement = NULL; + status_t error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + if (error != B_OK) { + data.SetToFormat("Unable to retrieve disassembly for IP %#" B_PRIx64 + ": %s\n", instructionPointer, strerror(error)); + _output << data; + return; + } + + DisassembledCode* code = instance->GetSourceCode(); + Function* function = instance->GetFunction(); + if (code == NULL) { + switch (function->SourceCodeState()) { + case FUNCTION_SOURCE_NOT_LOADED: + function->AddListener(this); + fSourceWaitingFunction = function; + fListener->FunctionSourceCodeRequested(instance, true); + // fall through + case FUNCTION_SOURCE_LOADING: + { + teamLocker.Unlock(); + error = acquire_sem(fTeamDataSem); + if (error != B_OK) + return; + teamLocker.Lock(); + break; + } + default: + return; + } + + if (instance->SourceCodeState() == FUNCTION_SOURCE_UNAVAILABLE) + return; + + error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + code = instance->GetSourceCode(); + } + + SourceLocation location = statement->StartSourceLocation(); + + _output << "\t\t\tDisassembly:\n"; + for (int32 i = 0; i < location.Line(); i++) { + _output << "\t\t\t\t" << code->LineAt(i); + if (i == location.Line() - 1) + _output << " <--"; + _output << "\n"; + } + _output << "\n"; +} + + +void DebugReportGenerator::_DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, uint8 stackDirection) { @@ -519,11 +600,11 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output, _output << "\t\t\tFrame memory:\n"; if (fBlockRetrievalStatus == B_OK) { - UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, + UiUtils::DumpMemory(_output, 4 , fCurrentBlock, startAddress, 1, 16, endAddress - startAddress); } else { BString data; - data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror( + data.SetToFormat("\t\t\t\tUnavailable (%s)\n", strerror( fBlockRetrievalStatus)); _output += data; } diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 13746e9..121bb5a 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -8,6 +8,7 @@ #include <Looper.h> +#include "Function.h" #include "Team.h" #include "TeamMemoryBlock.h" #include "ValueNodeContainer.h" @@ -30,7 +31,8 @@ class ValueNodeManager; class DebugReportGenerator : public BLooper, private Team::Listener, - private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { + private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener, + private Function::Listener { public: DebugReportGenerator(::Team* team, UserInterfaceListener* listener, @@ -58,6 +60,8 @@ private: // ValueNodeContainer::Listener virtual void ValueNodeValueChanged(ValueNode* node); + // Function::Listener + virtual void FunctionSourceCodeChanged(Function* function); private: status_t _GenerateReport(const entry_ref& outputPath); @@ -68,6 +72,8 @@ private: status_t _DumpRunningThreads(BString& _output); status_t _DumpDebuggedThreadInfo(BString& _output, ::Thread* thread); + void _DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer); void _DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, @@ -97,6 +103,7 @@ private: TeamMemoryBlock* fCurrentBlock; status_t fBlockRetrievalStatus; ::Thread* fTraceWaitingThread; + Function* fSourceWaitingFunction; }; #endif // DEBUG_REPORT_GENERATOR_H ############################################################################ Revision: hrev46063 Commit: 396a3d082f8e9535f0482b90731ee7965a266ce0 URL: http://cgit.haiku-os.org/haiku/commit/?id=396a3d0 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sun Sep 15 13:35:38 2013 UTC Merge branch 'debugger_report_add_disassembly' ----------------------------------------------------------------------------