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:
@@ -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,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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user