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
This commit is contained in:
Ingo Weinhold
2009-06-26 13:12:06 +00:00
parent 7f5bbbdc56
commit 125e089e1a
6 changed files with 113 additions and 65 deletions
+4 -2
View File
@@ -74,10 +74,12 @@ Architecture::CreateStackTrace(Team* team,
Reference<ImageDebugInfo> imageDebugInfoReference(imageDebugInfo, true);
// get the function
teamLocker.Lock();
FunctionDebugInfo* function = NULL;
if (imageDebugInfo != NULL)
function = imageDebugInfo->FindFunction(instructionPointer);
Reference<FunctionDebugInfo> functionReference(function, true);
function = imageDebugInfo->FunctionAtAddress(instructionPointer);
Reference<FunctionDebugInfo> functionReference(function);
teamLocker.Unlock();
// If the last frame had been created by the architecture, we update the
// CPU state.
+5 -2
View File
@@ -5,6 +5,7 @@
#ifndef DEBUG_INFO_H
#define DEBUG_INFO_H
#include <ObjectList.h>
#include <Referenceable.h>
#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<FunctionDebugInfo>& functions)
= 0;
// returns references
virtual status_t CreateFrame(Image* image,
FunctionDebugInfo* function,
@@ -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<FunctionDebugInfo>& functions)
{
SymbolInfo* symbolInfo = _FindSymbol(address);
if (symbolInfo == NULL || symbolInfo->Type() != B_SYMBOL_TYPE_TEXT)
return NULL;
BObjectList<SymbolInfo> 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;
}
@@ -7,8 +7,6 @@
#include <String.h>
#include <ObjectList.h>
#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<FunctionDebugInfo>& functions);
virtual status_t CreateFrame(Image* image,
FunctionDebugInfo* function,
CpuState* cpuState,
@@ -41,23 +40,13 @@ public:
Statement*& _statement);
private:
typedef BObjectList<SymbolInfo> 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;
};
@@ -8,6 +8,7 @@
#include <new>
#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;
}
+12 -2
View File
@@ -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<DebugInfo> DebugInfoList;
typedef BObjectList<FunctionDebugInfo> 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;
};