status_t TeamDebugInfo::LoadSourceCode(LocatableFile* file, FileSourceCode*& _sourceCode) { AutoLocker<BLocker> locker(fLock); // If we don't know the source file, there's nothing we can do. SourceFileEntry* entry = fSourceFiles->Lookup(file); if (entry == NULL) return B_ENTRY_NOT_FOUND; // the source might already be loaded FileSourceCode* sourceCode = entry->GetSourceCode(); if (sourceCode != NULL) { sourceCode->AcquireReference(); _sourceCode = sourceCode; return B_OK; } // get the source language from some function's image debug info Function* function = entry->FunctionAt(0); if (function == NULL) return B_ENTRY_NOT_FOUND; FunctionDebugInfo* functionDebugInfo = function->FirstInstance()->GetFunctionDebugInfo(); SourceLanguage* language; status_t error = functionDebugInfo->GetSpecificImageDebugInfo() ->GetSourceLanguage(functionDebugInfo, language); if (error != B_OK) return error; BReference<SourceLanguage> languageReference(language, true); // no source code yet // locker.Unlock(); // TODO: It would be nice to unlock here, but we need to iterate through // the images below. We could clone the list, acquire references, and // unlock. Then we have to compare the list with the then current list when // we're done loading. // load the source file SourceFile* sourceFile; error = fFileManager->LoadSourceFile(file, sourceFile); if (error != B_OK) return error; // create the source code sourceCode = new(std::nothrow) FileSourceCode(file, sourceFile, language); sourceFile->ReleaseReference(); if (sourceCode == NULL) return B_NO_MEMORY; BReference<FileSourceCode> sourceCodeReference(sourceCode, true); error = sourceCode->Init(); if (error != B_OK) return error; // Iterate through all images that know the source file and ask them to add // information. bool anyInfo = false; for (int32 i = 0; ImageDebugInfo* imageDebugInfo = fImages.ItemAt(i); i++) anyInfo |= imageDebugInfo->AddSourceCodeInfo(file, sourceCode) == B_OK; if (!anyInfo) return B_ENTRY_NOT_FOUND; entry->SetSourceCode(sourceCode); _sourceCode = sourceCodeReference.Detach(); return B_OK; }