Debugger: Adjustments to report generator.

DebugReportGenerator:
- Due to the changes made with respect to correctly handling switching to
  disassembly explicitly, the report generator needs to request loading
  source files as it walks the stack trace in order to get source-based
  line number information. Fixes crash reports having -1 as the line number
  in cases where debug information was available, but the user hadn't yet
  looked at the source file in question.

LoadSourceCodeJob:
- Cleanup.
This commit is contained in:
Rene Gollent 2016-12-07 23:55:36 -05:00
parent 83345e6b0b
commit 67e0301477
3 changed files with 60 additions and 11 deletions

View File

@ -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:

View File

@ -103,6 +103,7 @@ private:
TeamMemoryBlock* fCurrentBlock;
status_t fBlockRetrievalStatus;
::Thread* fTraceWaitingThread;
bool fSourceWaitForDisassembly;
Function* fSourceWaitingFunction;
};

View File

@ -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