diff --git a/src/kits/debugger/controllers/DebugReportGenerator.cpp b/src/kits/debugger/controllers/DebugReportGenerator.cpp index e9cd33c24d..0d6ef1023b 100644 --- a/src/kits/debugger/controllers/DebugReportGenerator.cpp +++ b/src/kits/debugger/controllers/DebugReportGenerator.cpp @@ -22,6 +22,7 @@ #include "DisassembledCode.h" #include "FunctionInstance.h" #include "Image.h" +#include "ImageDebugInfo.h" #include "MessageCodes.h" #include "Register.h" #include "SemaphoreInfo.h" @@ -64,6 +65,7 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, fCurrentBlock(NULL), fBlockRetrievalStatus(B_OK), fTraceWaitingThread(NULL), + fSourceWaitForDisassembly(false), fSourceWaitingFunction(NULL) { fTeam->AddListener(this); @@ -221,11 +223,22 @@ 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); + function_source_state state; + if (fSourceWaitForDisassembly) + state = function->FirstInstance()->SourceCodeState(); + else + state = function->SourceCodeState(); + + switch (state) { + case FUNCTION_SOURCE_LOADED: + case FUNCTION_SOURCE_SUPPRESSED: + case FUNCTION_SOURCE_UNAVAILABLE: + { + release_sem(fTeamDataSem); + // fall through + } + default: + break; } } } @@ -517,7 +530,39 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BFile& _output, BString sourcePath; target_addr_t ip = frame->InstructionPointer(); - FunctionInstance* functionInstance; + Image* image = fTeam->ImageByAddress(ip); + FunctionInstance* functionInstance = NULL; + if (image != NULL && image->ImageDebugInfoState() + == IMAGE_DEBUG_INFO_LOADED) { + ImageDebugInfo* info = image->GetImageDebugInfo(); + functionInstance = info->FunctionAtAddress(ip); + } + + if (functionInstance != NULL) { + Function* function = functionInstance->GetFunction(); + if (function->SourceCodeState() == FUNCTION_SOURCE_NOT_LOADED + && functionInstance->SourceCodeState() + == FUNCTION_SOURCE_NOT_LOADED) { + fSourceWaitingFunction = function; + fSourceWaitForDisassembly = false; + fSourceWaitingFunction->AddListener(this); + fListener->FunctionSourceCodeRequested(functionInstance); + + locker.Unlock(); + + do { + error = acquire_sem(fTeamDataSem); + } while (error == B_INTERRUPTED); + + if (error != B_OK) + break; + + locker.Lock(); + + fSourceWaitingFunction->RemoveListener(this); + } + } + Statement* statement; if (fTeam->GetStatementAtAddress(ip, functionInstance, statement) == B_OK) { @@ -634,6 +679,7 @@ DebugReportGenerator::_DumpFunctionDisassembly(BFile& _output, // function has been loaded, but the disassembly has not. function->AddListener(this); fSourceWaitingFunction = function; + fSourceWaitForDisassembly = true; fListener->FunctionSourceCodeRequested(instance, true); // fall through case FUNCTION_SOURCE_LOADING: @@ -647,6 +693,7 @@ DebugReportGenerator::_DumpFunctionDisassembly(BFile& _output, return error; teamLocker.Lock(); + fSourceWaitingFunction->RemoveListener(this); break; } default: diff --git a/src/kits/debugger/controllers/DebugReportGenerator.h b/src/kits/debugger/controllers/DebugReportGenerator.h index e88d62f2d7..b8d50df45c 100644 --- a/src/kits/debugger/controllers/DebugReportGenerator.h +++ b/src/kits/debugger/controllers/DebugReportGenerator.h @@ -103,6 +103,7 @@ private: TeamMemoryBlock* fCurrentBlock; status_t fBlockRetrievalStatus; ::Thread* fTraceWaitingThread; + bool fSourceWaitForDisassembly; Function* fSourceWaitingFunction; }; diff --git a/src/kits/debugger/jobs/LoadSourceCodeJob.cpp b/src/kits/debugger/jobs/LoadSourceCodeJob.cpp index 517ee64e0f..a014686c36 100644 --- a/src/kits/debugger/jobs/LoadSourceCodeJob.cpp +++ b/src/kits/debugger/jobs/LoadSourceCodeJob.cpp @@ -91,14 +91,15 @@ LoadSourceCodeJob::Do() // explicitly asked for disassembly. This needs to be done first // since Function will clear the disassembled code states of all // its child instances. + function_source_state state + = fLoadForFunction ? FUNCTION_SOURCE_LOADED + : FUNCTION_SOURCE_SUPPRESSED; if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) { - FileSourceCode* sourceCode = function->GetSourceCode(); - function->SetSourceCode(sourceCode, - FUNCTION_SOURCE_SUPPRESSED); + FileSourceCode* functionSourceCode = function->GetSourceCode(); + function->SetSourceCode(functionSourceCode, state); } - fFunctionInstance->SetSourceCode(sourceCode, - FUNCTION_SOURCE_SUPPRESSED); + fFunctionInstance->SetSourceCode(sourceCode, state); sourceCode->ReleaseReference(); } } else