status_t TeamDebugInfo::AddImageDebugInfo(ImageDebugInfo* imageDebugInfo) { AutoLocker<BLocker> locker(fLock); // We have both locks now, so that for read-only access either lock // suffices. if (!fImages.AddItem(imageDebugInfo)) return B_NO_MEMORY; // Match all of the image debug info's functions instances with functions. BObjectList<SourceFileEntry> sourceFileEntries; for (int32 i = 0; FunctionInstance* instance = imageDebugInfo->FunctionAt(i); i++) { // lookup the function or create it, if it doesn't exist yet Function* function = fFunctions->Lookup(instance); if (function != NULL) { // TODO: Also update possible user breakpoints in this function! function->AddInstance(instance); instance->SetFunction(function); // The new image debug info might have additional information about // the source file of the function, so remember the source file // entry. if (LocatableFile* sourceFile = function->SourceFile()) { SourceFileEntry* entry = fSourceFiles->Lookup(sourceFile); if (entry != NULL && entry->GetSourceCode() != NULL) sourceFileEntries.AddItem(entry); } } else { function = new(std::nothrow) Function; if (function == NULL) { RemoveImageDebugInfo(imageDebugInfo); return B_NO_MEMORY; } function->AddInstance(instance); instance->SetFunction(function); status_t error = _AddFunction(function); // Insert after adding the instance. Otherwise the function // wouldn't be hashable/comparable. if (error != B_OK) { function->RemoveInstance(instance); instance->SetFunction(NULL); RemoveImageDebugInfo(imageDebugInfo); return error; } } } // update the source files the image debug info knows about for (int32 i = 0; SourceFileEntry* entry = sourceFileEntries.ItemAt(i); i++) { FileSourceCode* sourceCode = entry->GetSourceCode(); sourceCode->Lock(); if (imageDebugInfo->AddSourceCodeInfo(entry->SourceFile(), sourceCode) == B_OK) { // TODO: Notify interesting parties! Iterate through all functions // for this source file? } sourceCode->Unlock(); } return B_OK; }