Files
haiku-beta6/src/kits/debugger/jobs/LoadSourceCodeJob.cpp
T
Rene Gollent 67e0301477 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.
2016-12-07 23:58:36 -05:00

110 lines
3.0 KiB
C++

/*
* Copyright 2012-2016, Rene Gollent, [email protected].
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "Jobs.h"
#include <AutoLocker.h>
#include "Architecture.h"
#include "DebuggerInterface.h"
#include "DisassembledCode.h"
#include "Function.h"
#include "FunctionInstance.h"
#include "FileSourceCode.h"
#include "Team.h"
#include "TeamDebugInfo.h"
LoadSourceCodeJob::LoadSourceCodeJob(
DebuggerInterface* debuggerInterface, Architecture* architecture,
Team* team, FunctionInstance* functionInstance, bool loadForFunction)
:
fKey(functionInstance, JOB_TYPE_LOAD_SOURCE_CODE),
fDebuggerInterface(debuggerInterface),
fArchitecture(architecture),
fTeam(team),
fFunctionInstance(functionInstance),
fLoadForFunction(loadForFunction)
{
fFunctionInstance->AcquireReference();
SetDescription("Loading source code for function %s",
fFunctionInstance->PrettyName().String());
}
LoadSourceCodeJob::~LoadSourceCodeJob()
{
fFunctionInstance->ReleaseReference();
}
const JobKey&
LoadSourceCodeJob::Key() const
{
return fKey;
}
status_t
LoadSourceCodeJob::Do()
{
// if requested, try loading the source code for the function
Function* function = fFunctionInstance->GetFunction();
if (fLoadForFunction) {
FileSourceCode* sourceCode;
status_t error = fTeam->DebugInfo()->LoadSourceCode(
function->SourceFile(), sourceCode);
AutoLocker<Team> locker(fTeam);
if (error == B_OK) {
function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
sourceCode->ReleaseReference();
return B_OK;
}
function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
}
// Only try to load the function instance code, if it's not overridden yet.
AutoLocker<Team> locker(fTeam);
if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
return B_OK;
locker.Unlock();
// disassemble the function
DisassembledCode* sourceCode = NULL;
status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
sourceCode);
// set the result
locker.Lock();
if (error == B_OK) {
if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
// various parts of the debugger expect functions to have only
// one of source or disassembly available. As such, if the current
// function had source code previously active, unset it when
// 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* functionSourceCode = function->GetSourceCode();
function->SetSourceCode(functionSourceCode, state);
}
fFunctionInstance->SetSourceCode(sourceCode, state);
sourceCode->ReleaseReference();
}
} else
fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
return error;
}