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. if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) { FileSourceCode* sourceCode = function->GetSourceCode(); function->SetSourceCode(sourceCode, FUNCTION_SOURCE_NOT_LOADED); } fFunctionInstance->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED); sourceCode->ReleaseReference(); } } else fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE); return error; }
void TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance) { if (functionInstance == fActiveFunction) return; AutoLocker< ::Team> locker(fTeam); if (fActiveFunction != NULL) { fActiveFunction->GetFunction()->RemoveListener(this); fActiveFunction->ReleaseReference(); } // to avoid listener feedback problems, first unset the active function and // set the new image, if any locker.Unlock(); fActiveFunction = NULL; if (functionInstance != NULL) _SetActiveImage(fTeam->ImageByAddress(functionInstance->Address())); fActiveFunction = functionInstance; locker.Lock(); SourceCode* sourceCode = NULL; BReference<SourceCode> sourceCodeReference; if (fActiveFunction != NULL) { fActiveFunction->AcquireReference(); fActiveFunction->GetFunction()->AddListener(this); Function* function = fActiveFunction->GetFunction(); sourceCode = function->GetSourceCode(); if (sourceCode == NULL) sourceCode = fActiveFunction->GetSourceCode(); sourceCodeReference.SetTo(sourceCode); // If the source code is not loaded yet, request it. if (function->SourceCodeState() == FUNCTION_SOURCE_NOT_LOADED) fListener->FunctionSourceCodeRequested(fActiveFunction); } locker.Unlock(); _SetActiveSourceCode(sourceCode); fImageFunctionsView->SetFunction(fActiveFunction); locker.Lock(); // look if our current stack trace has a frame matching the selected // function. If so, set it to match. StackFrame* matchingFrame = NULL; BReference<StackFrame> frameRef; if (fActiveStackTrace != NULL) { for (int32 i = 0; i < fActiveStackTrace->CountFrames(); i++) { StackFrame* frame = fActiveStackTrace->FrameAt(i); if (frame->Function() == fActiveFunction) { matchingFrame = frame; frameRef.SetTo(frame); break; } } } locker.Unlock(); if (matchingFrame != NULL) _SetActiveStackFrame(matchingFrame); }