diff --git a/headers/private/debug/debug_support.h b/headers/private/debug/debug_support.h index aa8165228d..5567c7522d 100644 --- a/headers/private/debug/debug_support.h +++ b/headers/private/debug/debug_support.h @@ -1,5 +1,6 @@ /* - * Copyright 2005-2009, Ingo Weinhold, bonefish@users.sf.net. + * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com * Distributed under the terms of the MIT License. */ #ifndef _DEBUG_SUPPORT_H @@ -61,7 +62,7 @@ status_t debug_get_stack_frame(debug_context *context, typedef struct debug_symbol_lookup_context debug_symbol_lookup_context; typedef struct debug_symbol_iterator debug_symbol_iterator; -status_t debug_create_symbol_lookup_context(team_id team, +status_t debug_create_symbol_lookup_context(team_id team, image_id image, debug_symbol_lookup_context **lookupContext); void debug_delete_symbol_lookup_context( debug_symbol_lookup_context *lookupContext); @@ -77,6 +78,9 @@ status_t debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext, status_t debug_create_image_symbol_iterator( debug_symbol_lookup_context* lookupContext, image_id imageID, debug_symbol_iterator** _iterator); + // imageID can be -1 if all images in the target team are + // desired, otherwise a valid image id is expected. + status_t debug_create_file_symbol_iterator(const char* path, debug_symbol_iterator** _iterator); void debug_delete_symbol_iterator(debug_symbol_iterator* iterator); diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index f1931fe9b5..4edcd9a6fc 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -578,9 +578,9 @@ DebuggerInterface::GetSymbolInfos(team_id team, image_id image, BObjectList& infos) { // create a lookup context -// TODO: It's too expensive to create a lookup context for each image! debug_symbol_lookup_context* lookupContext; - status_t error = debug_create_symbol_lookup_context(team, &lookupContext); + status_t error = debug_create_symbol_lookup_context(team, image, + &lookupContext); if (error != B_OK) return error; @@ -623,10 +623,9 @@ DebuggerInterface::GetSymbolInfo(team_id team, image_id image, const char* name, int32 symbolType, SymbolInfo& info) { // create a lookup context - // TODO: It's a bit expensive to create a lookup context just for one - // symbol! debug_symbol_lookup_context* lookupContext; - status_t error = debug_create_symbol_lookup_context(team, &lookupContext); + status_t error = debug_create_symbol_lookup_context(team, image, + &lookupContext); if (error != B_OK) return error; diff --git a/src/bin/debug/profile/SharedImage.cpp b/src/bin/debug/profile/SharedImage.cpp index e35a51d5fa..9d3f453e84 100644 --- a/src/bin/debug/profile/SharedImage.cpp +++ b/src/bin/debug/profile/SharedImage.cpp @@ -40,7 +40,8 @@ SharedImage::Init(team_id owner, image_id imageID) { // we need a temporary symbol lookup context debug_symbol_lookup_context* lookupContext; - status_t error = debug_create_symbol_lookup_context(owner, &lookupContext); + status_t error = debug_create_symbol_lookup_context(owner, imageID, + &lookupContext); if (error != B_OK) { fprintf(stderr, "%s: Failed to create symbol lookup context " "for team %ld: %s\n", kCommandName, owner, strerror(error)); diff --git a/src/kits/debug/SymbolLookup.cpp b/src/kits/debug/SymbolLookup.cpp index 2d259fb666..53f41d78ad 100644 --- a/src/kits/debug/SymbolLookup.cpp +++ b/src/kits/debug/SymbolLookup.cpp @@ -1,5 +1,6 @@ /* * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -220,11 +221,12 @@ private: // constructor -SymbolLookup::SymbolLookup(team_id team) +SymbolLookup::SymbolLookup(team_id team, image_id image) : RemoteMemoryAccessor(team), fDebugArea(NULL), - fImages() + fImages(), + fImageID(image) { } @@ -281,53 +283,23 @@ SymbolLookup::Init() } } - // create a list of the team's images image_info imageInfo; - int32 cookie = 0; - while (get_next_image_info(fTeam, &cookie, &imageInfo) == B_OK) { - Image* image; - - if (fTeam == B_SYSTEM_TEAM) { - // kernel image - KernelImage* kernelImage = new(std::nothrow) KernelImage; - if (kernelImage == NULL) - return B_NO_MEMORY; - - error = kernelImage->Init(imageInfo); - image = kernelImage; - } else if (!strcmp("commpage", imageInfo.name)) { - // commpage image - CommPageImage* commPageImage = new(std::nothrow) CommPageImage; - if (commPageImage == NULL) - return B_NO_MEMORY; - - error = commPageImage->Init(imageInfo); - image = commPageImage; - } else { - // userland image -- try to load an image file - ImageFile* imageFile = new(std::nothrow) ImageFile; - if (imageFile == NULL) - return B_NO_MEMORY; - - error = imageFile->Init(imageInfo); - image = imageFile; + if (fImageID < 0) { + // create a list of the team's images + int32 cookie = 0; + while (get_next_image_info(fTeam, &cookie, &imageInfo) == B_OK) { + error = _LoadImageInfo(imageInfo); + if (error != B_OK) + return error; } + } else { + error = get_image_info(fImageID, &imageInfo); + if (error != B_OK) + return error; - if (error != B_OK) { - // initialization error -- fall back to the loaded image - delete image; - - const image_t* loadedImage = _FindLoadedImageByID(imageInfo.id); - if (loadedImage == NULL) - continue; - - image = new(std::nothrow) LoadedImage(this, loadedImage, - Read(loadedImage->symhash[1])); - if (image == NULL) - return B_NO_MEMORY; - } - - fImages.Add(image); + error = _LoadImageInfo(imageInfo); + if (error != B_OK) + return error; } return B_OK; @@ -534,6 +506,58 @@ SymbolLookup::_SymbolNameLen(const char* address) const } +status_t +SymbolLookup::_LoadImageInfo(const image_info& imageInfo) +{ + status_t error = B_OK; + + Image* image; + if (fTeam == B_SYSTEM_TEAM) { + // kernel image + KernelImage* kernelImage = new(std::nothrow) KernelImage; + if (kernelImage == NULL) + return B_NO_MEMORY; + + error = kernelImage->Init(imageInfo); + image = kernelImage; + } else if (!strcmp("commpage", imageInfo.name)) { + // commpage image + CommPageImage* commPageImage = new(std::nothrow) CommPageImage; + if (commPageImage == NULL) + return B_NO_MEMORY; + + error = commPageImage->Init(imageInfo); + image = commPageImage; + } else { + // userland image -- try to load an image file + ImageFile* imageFile = new(std::nothrow) ImageFile; + if (imageFile == NULL) + return B_NO_MEMORY; + + error = imageFile->Init(imageInfo); + image = imageFile; + } + + if (error != B_OK) { + // initialization error -- fall back to the loaded image + delete image; + + const image_t* loadedImage = _FindLoadedImageByID(imageInfo.id); + if (loadedImage == NULL) + return B_OK; + + image = new(std::nothrow) LoadedImage(this, loadedImage, + Read(loadedImage->symhash[1])); + if (image == NULL) + return B_NO_MEMORY; + + } + + fImages.Add(image); + + return B_OK; +} + // #pragma mark - LoadedImage diff --git a/src/kits/debug/SymbolLookup.h b/src/kits/debug/SymbolLookup.h index c7890c3b68..4631c02662 100644 --- a/src/kits/debug/SymbolLookup.h +++ b/src/kits/debug/SymbolLookup.h @@ -1,5 +1,6 @@ /* * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -136,7 +137,7 @@ struct SymbolIterator { // SymbolLookup class SymbolLookup : private RemoteMemoryAccessor { public: - SymbolLookup(team_id team); + SymbolLookup(team_id team, image_id image); ~SymbolLookup(); status_t Init(); @@ -166,10 +167,12 @@ private: Image* _FindImageAtAddress(addr_t address) const; Image* _FindImageByID(image_id id) const; size_t _SymbolNameLen(const char* address) const; + status_t _LoadImageInfo(const image_info& imageInfo); private: const runtime_loader_debug_area *fDebugArea; DoublyLinkedList fImages; + image_id fImageID; }; } // namespace Debug diff --git a/src/kits/debug/debug_support.cpp b/src/kits/debug/debug_support.cpp index e5691fb6dc..fdc231d3a9 100644 --- a/src/kits/debug/debug_support.cpp +++ b/src/kits/debug/debug_support.cpp @@ -1,6 +1,6 @@ /* * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010, Rene Gollent, rene@gollent.com. + * Copyright 2010-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -345,7 +345,7 @@ debug_get_stack_frame(debug_context *context, void *stackFrameAddress, // debug_create_symbol_lookup_context status_t -debug_create_symbol_lookup_context(team_id team, +debug_create_symbol_lookup_context(team_id team, image_id image, debug_symbol_lookup_context **_lookupContext) { if (team < 0 || !_lookupContext) @@ -359,7 +359,7 @@ debug_create_symbol_lookup_context(team_id team, ObjectDeleter contextDeleter(lookupContext); // create and init symbol lookup - SymbolLookup *lookup = new(std::nothrow) SymbolLookup(team); + SymbolLookup *lookup = new(std::nothrow) SymbolLookup(team, image); if (lookup == NULL) return B_NO_MEMORY; ObjectDeleter lookupDeleter(lookup); diff --git a/src/servers/debug/DebugServer.cpp b/src/servers/debug/DebugServer.cpp index 9f11b30114..9a8ec744d5 100644 --- a/src/servers/debug/DebugServer.cpp +++ b/src/servers/debug/DebugServer.cpp @@ -799,7 +799,7 @@ TeamDebugHandler::_PrintStackTrace(thread_id thread) if (error == B_OK) { // create a symbol lookup context debug_symbol_lookup_context *lookupContext = NULL; - error = debug_create_symbol_lookup_context(fTeam, &lookupContext); + error = debug_create_symbol_lookup_context(fTeam, -1, &lookupContext); if (error != B_OK) { debug_printf("debug_server: Failed to create symbol lookup " "context: %s\n", strerror(error));