From eb333098fe361d36e330fe35707a75a21b18686f Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 18 Sep 2008 00:15:44 +0000 Subject: [PATCH] Added work-around for a runtime loader problem after fork(). Its image structures still have the parent IDs, so finding an image by ID would fail in this case. We do now fall back to getting the image's text base address and finding the image by address. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27607 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/debug/SymbolLookup.cpp | 31 ++++++++++++++++++++++++++++++- src/kits/debug/SymbolLookup.h | 2 ++ src/kits/debug/debug_support.cpp | 20 ++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/kits/debug/SymbolLookup.cpp b/src/kits/debug/SymbolLookup.cpp index 816f1a19d9..16ad71efbd 100644 --- a/src/kits/debug/SymbolLookup.cpp +++ b/src/kits/debug/SymbolLookup.cpp @@ -283,10 +283,39 @@ SymbolLookup::LookupSymbolAddress(addr_t address, addr_t *_baseAddress, status_t SymbolLookup::InitSymbolIterator(image_id imageID, SymbolIterator& iterator) { + TRACE(("SymbolLookup::InitSymbolIterator(): image ID: %ld\n", imageID)); + // find the image const image_t* image = _FindImageByID(imageID); - if (image == NULL) + if (image == NULL) { + TRACE(("SymbolLookup::InitSymbolIterator() done: image not found\n")); return B_ENTRY_NOT_FOUND; + } + + iterator.image = image; + iterator.symbolCount = Read(image->symhash[1]); + iterator.textDelta = image->regions->delta; + iterator.currentIndex = -1; + + return B_OK; +} + + +// InitSymbolIterator +status_t +SymbolLookup::InitSymbolIteratorByAddress(addr_t address, + SymbolIterator& iterator) +{ + TRACE(("SymbolLookup::InitSymbolIteratorByAddress(): base address: %#lx\n", + address)); + + // find the image + const image_t *image = _FindImageAtAddress(address); + if (image == NULL) { + TRACE(("SymbolLookup::InitSymbolIteratorByAddress() done: image not " + "found\n")); + return B_ENTRY_NOT_FOUND; + } iterator.image = image; iterator.symbolCount = Read(image->symhash[1]); diff --git a/src/kits/debug/SymbolLookup.h b/src/kits/debug/SymbolLookup.h index 7a7a394d47..89606842fb 100644 --- a/src/kits/debug/SymbolLookup.h +++ b/src/kits/debug/SymbolLookup.h @@ -139,6 +139,8 @@ public: const char **_symbolName, const char **_imageName, bool *_exactMatch); status_t InitSymbolIterator(image_id imageID, SymbolIterator& iterator); + status_t InitSymbolIteratorByAddress(addr_t address, + SymbolIterator& iterator); status_t NextSymbol(SymbolIterator& iterator, const char** _symbolName, addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType); diff --git a/src/kits/debug/debug_support.cpp b/src/kits/debug/debug_support.cpp index 3ee453cb82..68ec20e936 100644 --- a/src/kits/debug/debug_support.cpp +++ b/src/kits/debug/debug_support.cpp @@ -378,6 +378,26 @@ debug_create_image_symbol_iterator(debug_symbol_lookup_context* lookupContext, error = exception.Error(); } + // Work-around for a runtime loader problem. A freshly fork()ed child does + // still have image_t structures with the parent's image ID's, so we + // wouldn't find the image in this case. + if (error != B_OK) { + // Get the image info and re-try looking with the text base address. + // Note, that we can't easily check whether the image is part of the + // target team at all (there's no image_info::team, we'd have to + // iterate through all images). + image_info imageInfo; + error = get_image_info(imageID, &imageInfo); + if (error == B_OK) { + try { + error = lookup->InitSymbolIteratorByAddress( + (addr_t)imageInfo.text, *iterator); + } catch (BPrivate::Exception exception) { + error = exception.Error(); + } + } + } + if (error != B_OK) { delete iterator; return error;