From 125e089e1a1a17b89ea7537d9265634ea873333a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 26 Jun 2009 13:12:06 +0000 Subject: [PATCH] ImageDebugInfo does now gather function debug infos from all available sources on init, keeping the most expressive one for each function. The interface changed accordingly, i.e. it is now possible to iterate through the functions and FindFunction() is now called FunctionAtAddress(), not returning a reference anymore. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31251 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/arch/Architecture.cpp | 6 +- src/apps/debugger/debug_info/DebugInfo.h | 7 +- .../debugger/debug_info/DebuggerDebugInfo.cpp | 66 ++++++++--------- .../debugger/debug_info/DebuggerDebugInfo.h | 15 +--- .../debugger/debug_info/ImageDebugInfo.cpp | 70 ++++++++++++++++--- src/apps/debugger/debug_info/ImageDebugInfo.h | 14 +++- 6 files changed, 113 insertions(+), 65 deletions(-) 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; };