From d20817c284da53a3b4b229ff20c525106d1e00ee Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 10 Jan 2025 21:11:26 -0500 Subject: [PATCH] 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 Tested-by: Commit checker robot --- src/kits/debug/SymbolLookup.cpp | 172 ++++++++++++++------------------ src/kits/debug/SymbolLookup.h | 38 ++++--- 2 files changed, 92 insertions(+), 118 deletions(-) diff --git a/src/kits/debug/SymbolLookup.cpp b/src/kits/debug/SymbolLookup.cpp index f862b6a5ee..9205aa813b 100644 --- a/src/kits/debug/SymbolLookup.cpp +++ b/src/kits/debug/SymbolLookup.cpp @@ -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)) - return *area; + 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); } - TRACE(("RemoteMemoryAccessor::_FindArea(): No area found for address %p\n", - address)); - throw Exception(B_ENTRY_NOT_FOUND); + return *area; } -// _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)); diff --git a/src/kits/debug/SymbolLookup.h b/src/kits/debug/SymbolLookup.h index 7bc0aaaec9..c57fb57e7b 100644 --- a/src/kits/debug/SymbolLookup.h +++ b/src/kits/debug/SymbolLookup.h @@ -49,11 +49,10 @@ private: // Area class Area : public DoublyLinkedListLinkImpl { 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 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 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;