Debug Kit: Build the areas list on-demand.

Now that we don't need to know the area IDs when cloning addresses
from the remote team, we can build the areas list lazily using just
the information returned from the debug nub thread.

Change-Id: I8a6344704273f0bc60af2fa78e39336c21995401
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8822
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
Augustin Cavalier 2025-01-10 21:11:26 -05:00 committed by waddlesplash
parent 2c9560581b
commit d20817c284
2 changed files with 92 additions and 118 deletions

View File

@ -31,47 +31,16 @@
using namespace BPrivate::Debug;
// PrepareAddress
const void *
Area::PrepareAddress(debug_context* debugContext, const void *address)
Area::TranslateAddress(const void *address)
{
TRACE(("Area::PrepareAddress(%p): area: %" B_PRId32 "\n", address, fRemoteID));
// clone the area, if not done already
if (fLocalID < 0) {
debug_nub_clone_area message;
message.reply_port = debugContext->reply_port;
message.address = address;
debug_nub_clone_area_reply reply;
status_t error = send_debug_message(debugContext, B_DEBUG_MESSAGE_CLONE_AREA,
&message, sizeof(message), &reply, sizeof(reply));
if (error != B_OK)
throw Exception(error);
fLocalID = reply.area;
if (fLocalID < 0) {
TRACE(("Area::PrepareAddress(): Failed to clone area %" B_PRId32
": %s\n", fRemoteID, strerror(fLocalID)));
throw Exception(fLocalID);
}
area_info info;
error = get_area_info(fLocalID, &info);
if (error < 0) {
TRACE(("Area::PrepareAddress(): Failed to get info for %" B_PRId32
": %s\n", fLocalID, strerror(info)));
throw Exception(fLocalID);
}
fLocalAddress = info.address;
}
TRACE(("Area::TranslateAddress(%p): area: %" B_PRId32 "\n", address, fLocalID));
// translate the address
const void *result = (const void*)((addr_t)address - (addr_t)fRemoteAddress
+ (addr_t)fLocalAddress);
TRACE(("Area::PrepareAddress(%p) done: %p\n", address, result));
TRACE(("Area::TranslateAddress(%p) done: %p\n", address, result));
return result;
}
@ -79,14 +48,13 @@ Area::PrepareAddress(debug_context* debugContext, const void *address)
// #pragma mark -
// constructor
RemoteMemoryAccessor::RemoteMemoryAccessor(debug_context* debugContext)
: fDebugContext(debugContext),
fAreas()
{
}
// destructor
RemoteMemoryAccessor::~RemoteMemoryAccessor()
{
// delete the areas
@ -96,70 +64,40 @@ RemoteMemoryAccessor::~RemoteMemoryAccessor()
}
}
// Init
status_t
RemoteMemoryAccessor::Init()
{
// If we don't have a debug context, then there's nothing we can do.
// Only SymbolLookup's image file functionality will be available.
if (fDebugContext == NULL || fDebugContext->nub_port < 0)
return B_OK;
// get a list of the team's areas
area_info areaInfo;
ssize_t cookie = 0;
status_t error;
while ((error = get_next_area_info(fDebugContext->team, &cookie, &areaInfo)) == B_OK) {
TRACE(("area %" B_PRId32 ": address: %p, size: %ld, name: %s\n",
areaInfo.area, areaInfo.address, areaInfo.size, areaInfo.name));
Area *area = new(std::nothrow) Area(areaInfo.area, areaInfo.address,
areaInfo.size);
if (!area)
return B_NO_MEMORY;
fAreas.Add(area);
}
if (fAreas.IsEmpty())
return error;
return B_OK;
}
// PrepareAddress
const void *
RemoteMemoryAccessor::PrepareAddress(const void *remoteAddress,
int32 size) const
int32 size)
{
TRACE(("RemoteMemoryAccessor::PrepareAddress(%p, %" B_PRId32 ")\n",
remoteAddress, size));
if (!remoteAddress) {
if (remoteAddress == NULL) {
TRACE(("RemoteMemoryAccessor::PrepareAddress(): Got null address!\n"));
throw Exception(B_BAD_VALUE);
}
return _FindArea(remoteAddress, size).PrepareAddress(fDebugContext, remoteAddress);
return _GetArea(remoteAddress, size).TranslateAddress(remoteAddress);
}
const void *
RemoteMemoryAccessor::PrepareAddressNoThrow(const void *remoteAddress,
int32 size) const
int32 size)
{
if (remoteAddress == NULL)
return NULL;
Area* area = _FindAreaNoThrow(remoteAddress, size);
if (area == NULL)
Area* area;
status_t status = _GetAreaNoThrow(remoteAddress, size, area);
if (status != B_OK)
return NULL;
return area->PrepareAddress(fDebugContext, remoteAddress);
return area->TranslateAddress(remoteAddress);
}
// AreaForLocalAddress
Area*
RemoteMemoryAccessor::AreaForLocalAddress(const void* address) const
{
@ -176,36 +114,78 @@ RemoteMemoryAccessor::AreaForLocalAddress(const void* address) const
}
// _FindArea
Area &
RemoteMemoryAccessor::_FindArea(const void *address, int32 size) const
RemoteMemoryAccessor::_GetArea(const void *address, int32 size)
{
TRACE(("RemoteMemoryAccessor::_FindArea(%p, %" B_PRId32 ")\n", address,
TRACE(("RemoteMemoryAccessor::_GetArea(%p, %" B_PRId32 ")\n", address,
size));
for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) {
Area *area = it.Next();
if (area->ContainsAddress(address, size))
Area* area;
status_t status = _GetAreaNoThrow(address, size, area);
if (status != B_OK) {
TRACE(("RemoteMemoryAccessor::_GetArea(): Failed to get address %p\n",
address));
throw Exception(status);
}
return *area;
}
TRACE(("RemoteMemoryAccessor::_FindArea(): No area found for address %p\n",
address));
throw Exception(B_ENTRY_NOT_FOUND);
}
// _FindAreaNoThrow
Area*
RemoteMemoryAccessor::_FindAreaNoThrow(const void *address, int32 size) const
status_t
RemoteMemoryAccessor::_GetAreaNoThrow(const void *address, int32 size, Area *&_area)
{
for (AreaList::ConstIterator it = fAreas.GetIterator(); it.HasNext();) {
for (AreaList::Iterator it = fAreas.GetIterator(); it.HasNext();) {
Area *area = it.Next();
if (area->ContainsAddress(address, size))
return area;
if (area->ContainsAddress(address, size)) {
_area = area;
return B_OK;
}
}
return NULL;
// If we don't have a debug context, then there's nothing we can do.
// SymbolLookup's image file functionality will still be available, though.
if (fDebugContext == NULL || fDebugContext->nub_port < 0)
return B_NO_INIT;
// we need to clone a new area
debug_nub_clone_area message;
message.reply_port = fDebugContext->reply_port;
message.address = address;
debug_nub_clone_area_reply reply;
status_t error = send_debug_message(fDebugContext, B_DEBUG_MESSAGE_CLONE_AREA,
&message, sizeof(message), &reply, sizeof(reply));
if (error != B_OK)
return error;
area_id localID = reply.area;
if (localID < 0) {
TRACE(("RemoteMemoryAccessor: Failed to clone area for %p: %s\n",
address, strerror(localID)));
return localID;
}
area_info areaInfo;
error = get_area_info(localID, &areaInfo);
if (error < 0) {
TRACE(("RemoteMemoryAccessor: Failed to get info for %" B_PRId32
": %s\n", localID, strerror(error)));
return error;
}
const addr_t remoteBaseAddress = (addr_t)address
- ((addr_t)reply.address - (addr_t)areaInfo.address);
Area *area = new(std::nothrow) Area(localID,
remoteBaseAddress, areaInfo.address, areaInfo.size);
if (area == NULL)
return B_NO_MEMORY;
fAreas.Add(area);
_area = area;
return B_OK;
}
@ -265,9 +245,7 @@ SymbolLookup::Init()
{
TRACE(("SymbolLookup::Init()\n"));
status_t error = RemoteMemoryAccessor::Init();
if (error != B_OK)
return error;
status_t error = 0;
if (fDebugContext->team != B_SYSTEM_TEAM) {
TRACE(("SymbolLookup::Init(): searching debug area...\n"));
@ -444,7 +422,7 @@ SymbolLookup::GetSymbol(image_id imageID, const char* name, int32 symbolType,
// _FindLoadedImageAtAddress
const image_t *
SymbolLookup::_FindLoadedImageAtAddress(addr_t address) const
SymbolLookup::_FindLoadedImageAtAddress(addr_t address)
{
TRACE(("SymbolLookup::_FindLoadedImageAtAddress(%p)\n", (void*)address));
@ -469,7 +447,7 @@ SymbolLookup::_FindLoadedImageAtAddress(addr_t address) const
// _FindLoadedImageByID
const image_t*
SymbolLookup::_FindLoadedImageByID(image_id id) const
SymbolLookup::_FindLoadedImageByID(image_id id)
{
TRACE(("SymbolLookup::_FindLoadedImageByID(%" B_PRId32 ")\n", id));

View File

@ -49,11 +49,10 @@ private:
// Area
class Area : public DoublyLinkedListLinkImpl<Area> {
public:
Area(area_id id, const void *address, int32 size)
: fRemoteID(id),
fLocalID(-1),
fRemoteAddress(address),
fLocalAddress(NULL),
Area(area_id localID, addr_t remoteAddress, const void* localAddress, int32 size)
: fLocalID(localID),
fRemoteAddress(remoteAddress),
fLocalAddress(localAddress),
fSize(size)
{
}
@ -64,14 +63,14 @@ public:
delete_area(fLocalID);
}
const void* RemoteAddress() const { return fRemoteAddress; }
addr_t RemoteAddress() const { return fRemoteAddress; }
const void* LocalAddress() const { return fLocalAddress; }
int32 Size() const { return fSize; }
bool ContainsAddress(const void *address, int32 size) const
{
return ((addr_t)fRemoteAddress <= (addr_t)address
&& (addr_t)address + size <= (addr_t)fRemoteAddress + fSize);
return (fRemoteAddress <= (addr_t)address
&& (addr_t)address + size <= (fRemoteAddress + fSize));
}
bool ContainsLocalAddress(const void* address) const
@ -80,13 +79,12 @@ public:
&& (addr_t)address < (addr_t)fLocalAddress + fSize;
}
const void *PrepareAddress(debug_context* debugContext, const void *address);
const void *TranslateAddress(const void *remoteAddress);
private:
area_id fRemoteID;
area_id fLocalID;
const void *fRemoteAddress;
void *fLocalAddress;
addr_t fRemoteAddress;
const void *fLocalAddress;
int32 fSize;
};
@ -97,14 +95,12 @@ public:
RemoteMemoryAccessor(debug_context* debugContext);
~RemoteMemoryAccessor();
status_t Init();
const void *PrepareAddress(const void *remoteAddress, int32 size) const;
const void *PrepareAddress(const void *remoteAddress, int32 size);
const void *PrepareAddressNoThrow(const void *remoteAddress,
int32 size) const;
int32 size);
template<typename Type> inline const Type &Read(
const Type &remoteData) const
const Type &remoteData)
{
const void *remoteAddress = &remoteData;
const void *localAddress = PrepareAddress(remoteAddress,
@ -115,8 +111,8 @@ public:
Area* AreaForLocalAddress(const void* address) const;
private:
Area &_FindArea(const void *address, int32 size) const;
Area* _FindAreaNoThrow(const void *address, int32 size) const;
Area& _GetArea(const void *address, int32 size);
status_t _GetAreaNoThrow(const void *address, int32 size, Area *&_area);
typedef DoublyLinkedList<Area> AreaList;
@ -163,8 +159,8 @@ private:
friend class LoadedImage;
private:
const image_t* _FindLoadedImageAtAddress(addr_t address) const;
const image_t* _FindLoadedImageByID(image_id id) const;
const image_t* _FindLoadedImageAtAddress(addr_t address);
const image_t* _FindLoadedImageByID(image_id id);
Image* _FindImageAtAddress(addr_t address) const;
Image* _FindImageByID(image_id id) const;
size_t _SymbolNameLen(const char* address) const;