diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index acf46f2b4b..5ed743a0d7 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -74,10 +74,12 @@ Architecture::CreateStackTrace(Team* team, Reference imageDebugInfoReference(imageDebugInfo, true); // get the function + teamLocker.Lock(); FunctionDebugInfo* function = NULL; if (imageDebugInfo != NULL) - function = imageDebugInfo->FindFunction(instructionPointer); - Reference functionReference(function, true); + function = imageDebugInfo->FunctionAtAddress(instructionPointer); + Reference functionReference(function); + teamLocker.Unlock(); // If the last frame had been created by the architecture, we update the // CPU state. diff --git a/src/apps/debugger/debug_info/DebugInfo.h b/src/apps/debugger/debug_info/DebugInfo.h index 7482cf8dd4..73af62c001 100644 --- a/src/apps/debugger/debug_info/DebugInfo.h +++ b/src/apps/debugger/debug_info/DebugInfo.h @@ -5,6 +5,7 @@ #ifndef DEBUG_INFO_H #define DEBUG_INFO_H +#include #include #include "ArchitectureTypes.h" @@ -24,8 +25,10 @@ class DebugInfo : public Referenceable { public: virtual ~DebugInfo(); - virtual FunctionDebugInfo* FindFunction(target_addr_t address) = 0; - // returns a reference + virtual status_t GetFunctions( + BObjectList& functions) + = 0; + // returns references virtual status_t CreateFrame(Image* image, FunctionDebugInfo* function, diff --git a/src/apps/debugger/debug_info/DebuggerDebugInfo.cpp b/src/apps/debugger/debug_info/DebuggerDebugInfo.cpp index 9a1b71d684..8a6875b3af 100644 --- a/src/apps/debugger/debug_info/DebuggerDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DebuggerDebugInfo.cpp @@ -22,8 +22,7 @@ DebuggerDebugInfo::DebuggerDebugInfo(const ImageInfo& imageInfo, : fImageInfo(imageInfo), fDebuggerInterface(debuggerInterface), - fArchitecture(architecture), - fSymbols(20, true) + fArchitecture(architecture) { } @@ -36,30 +35,40 @@ DebuggerDebugInfo::~DebuggerDebugInfo() status_t DebuggerDebugInfo::Init() { - // TODO: Extend DebuggerInterface to find a symbol on demand! - - status_t error = fDebuggerInterface->GetSymbolInfos(fImageInfo.TeamID(), - fImageInfo.ImageID(), fSymbols); - if (error != B_OK) - return error; - - // sort the symbols - fSymbols.SortItems(&_CompareSymbols); - return B_OK; } -FunctionDebugInfo* -DebuggerDebugInfo::FindFunction(target_addr_t address) +status_t +DebuggerDebugInfo::GetFunctions(BObjectList& functions) { - SymbolInfo* symbolInfo = _FindSymbol(address); - if (symbolInfo == NULL || symbolInfo->Type() != B_SYMBOL_TYPE_TEXT) - return NULL; + BObjectList symbols(20, true); + status_t error = fDebuggerInterface->GetSymbolInfos(fImageInfo.TeamID(), + fImageInfo.ImageID(), symbols); + if (error != B_OK) + return error; - return new(std::nothrow) BasicFunctionDebugInfo(this, symbolInfo->Address(), - symbolInfo->Size(), symbolInfo->Name(), - Demangler::Demangle(symbolInfo->Name())); + // sort the symbols -- not necessary, but a courtesy to ImageDebugInfo which + // will peform better when inserting functions at the end of a list + symbols.SortItems(&_CompareSymbols); + + // create the function infos + for (int32 i = 0; SymbolInfo* symbol = symbols.ItemAt(i); i++) { + FunctionDebugInfo* function = new(std::nothrow) BasicFunctionDebugInfo( + this, symbol->Address(), symbol->Size(), symbol->Name(), + Demangler::Demangle(symbol->Name())); + if (function == NULL || !functions.AddItem(function)) { + delete function; + int32 index = functions.CountItems() - 1; + for (i--; i >= 0; i--, index--) { + function = functions.RemoveItemAt(index); + delete function; + } + return B_NO_MEMORY; + } + } + + return B_OK; } @@ -103,26 +112,9 @@ DebuggerDebugInfo::GetStatement(FunctionDebugInfo* function, } -SymbolInfo* -DebuggerDebugInfo::_FindSymbol(target_addr_t address) -{ - return fSymbols.BinarySearchByKey(address, &_CompareAddressSymbol); -} - - /*static*/ int DebuggerDebugInfo::_CompareSymbols(const SymbolInfo* a, const SymbolInfo* b) { return a->Address() < b->Address() ? -1 : (a->Address() == b->Address() ? 0 : 1); } - - -/*static*/ int -DebuggerDebugInfo::_CompareAddressSymbol(const target_addr_t* address, - const SymbolInfo* info) -{ - if (*address < info->Address()) - return -1; - return *address < info->Address() + info->Size() ? 0 : 1; -} diff --git a/src/apps/debugger/debug_info/DebuggerDebugInfo.h b/src/apps/debugger/debug_info/DebuggerDebugInfo.h index 41a874cb21..a74f17f27d 100644 --- a/src/apps/debugger/debug_info/DebuggerDebugInfo.h +++ b/src/apps/debugger/debug_info/DebuggerDebugInfo.h @@ -7,8 +7,6 @@ #include -#include - #include "DebugInfo.h" #include "ImageInfo.h" @@ -28,7 +26,8 @@ public: status_t Init(); - virtual FunctionDebugInfo* FindFunction(target_addr_t address); + virtual status_t GetFunctions( + BObjectList& functions); virtual status_t CreateFrame(Image* image, FunctionDebugInfo* function, CpuState* cpuState, @@ -41,23 +40,13 @@ public: Statement*& _statement); private: - typedef BObjectList SymbolList; - - struct FindByAddressPredicate; - -private: - SymbolInfo* _FindSymbol(target_addr_t address); static int _CompareSymbols(const SymbolInfo* a, const SymbolInfo* b); - static int _CompareAddressSymbol( - const target_addr_t* address, - const SymbolInfo* info); private: ImageInfo fImageInfo; DebuggerInterface* fDebuggerInterface; Architecture* fArchitecture; - SymbolList fSymbols; }; diff --git a/src/apps/debugger/debug_info/ImageDebugInfo.cpp b/src/apps/debugger/debug_info/ImageDebugInfo.cpp index bc7014c7ca..5713358411 100644 --- a/src/apps/debugger/debug_info/ImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/ImageDebugInfo.cpp @@ -8,6 +8,7 @@ #include #include "DebuggerDebugInfo.h" +#include "FunctionDebugInfo.h" ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo, @@ -22,6 +23,8 @@ ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo, ImageDebugInfo::~ImageDebugInfo() { + for (int32 i = 0; FunctionDebugInfo* function = fFunctions.ItemAt(i); i++) + function->RemoveReference(); } @@ -50,18 +53,67 @@ ImageDebugInfo::Init() // only "no memory" is fatal } + // get functions -- get them from most expressive debug info first and add + // missing functions from less expressive debug infos + for (int32 i = 0; DebugInfo* debugInfo = fDebugInfos.ItemAt(i); i++) { + FunctionList functions; + status_t error = debugInfo->GetFunctions(functions); + if (error != B_OK) + return error; + + for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k); + k++) { + if (FunctionAtAddress(function->Address()) == NULL) { + if (!fFunctions.BinaryInsert(function, &_CompareFunctions)) { + for (; (function = functions.ItemAt(k)); k++) { + function->RemoveReference(); + return B_NO_MEMORY; + } + } + } else + function->RemoveReference(); + } + } + return B_OK; } -FunctionDebugInfo* -ImageDebugInfo::FindFunction(target_addr_t address) +int32 +ImageDebugInfo::CountFunctions() const { - for (int32 i = 0; DebugInfo* debugInfo = fDebugInfos.ItemAt(i); i++) { - FunctionDebugInfo* functionInfo = debugInfo->FindFunction(address); - if (functionInfo) - return functionInfo; - } - - return NULL; + return fFunctions.CountItems(); +} + + +FunctionDebugInfo* +ImageDebugInfo::FunctionAt(int32 index) const +{ + return fFunctions.ItemAt(index); +} + + +FunctionDebugInfo* +ImageDebugInfo::FunctionAtAddress(target_addr_t address) const +{ + return fFunctions.BinarySearchByKey(address, &_CompareAddressFunction); +} + + +/*static*/ int +ImageDebugInfo::_CompareFunctions(const FunctionDebugInfo* a, + const FunctionDebugInfo* b) +{ + return a->Address() < b->Address() + ? -1 : (a->Address() == b->Address() ? 0 : 1); +} + + +/*static*/ int +ImageDebugInfo::_CompareAddressFunction(const target_addr_t* address, + const FunctionDebugInfo* function) +{ + if (*address < function->Address()) + return -1; + return *address < function->Address() + function->Size() ? 0 : 1; } diff --git a/src/apps/debugger/debug_info/ImageDebugInfo.h b/src/apps/debugger/debug_info/ImageDebugInfo.h index e38db02102..ff8d3b6531 100644 --- a/src/apps/debugger/debug_info/ImageDebugInfo.h +++ b/src/apps/debugger/debug_info/ImageDebugInfo.h @@ -29,17 +29,27 @@ public: status_t Init(); - FunctionDebugInfo* FindFunction(target_addr_t address); - // returns a reference + int32 CountFunctions() const; + FunctionDebugInfo* FunctionAt(int32 index) const; + FunctionDebugInfo* FunctionAtAddress(target_addr_t address) const; private: typedef BObjectList DebugInfoList; + typedef BObjectList FunctionList; + +private: + static int _CompareFunctions(const FunctionDebugInfo* a, + const FunctionDebugInfo* b); + static int _CompareAddressFunction( + const target_addr_t* address, + const FunctionDebugInfo* function); private: ImageInfo fImageInfo; DebuggerInterface* fDebuggerInterface; Architecture* fArchitecture; DebugInfoList fDebugInfos; + FunctionList fFunctions; };