diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 46e146dc7f..dbf24e39a2 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -24,6 +24,7 @@ #include "CommandLineUserInterface.h" #include "GraphicalUserInterface.h" +#include "ImageDebugLoadingStateHandlerRoster.h" #include "MessageCodes.h" #include "SettingsManager.h" #include "SignalSet.h" @@ -212,6 +213,10 @@ global_init() if (error != B_OK) return error; + error = ImageDebugLoadingStateHandlerRoster::CreateDefault(); + if (error != B_OK) + return error; + return B_OK; } @@ -402,6 +407,7 @@ Debugger::~Debugger() { ValueHandlerRoster::DeleteDefault(); TypeHandlerRoster::DeleteDefault(); + ImageDebugLoadingStateHandlerRoster::DeleteDefault(); } diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 95550ffc67..e7f38affb0 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -14,6 +14,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86_64 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) controllers ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info loading_state_handlers ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_managers ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ; @@ -112,6 +113,8 @@ Application Debugger : ImageDebugInfo.cpp ImageDebugInfoLoadingState.cpp ImageDebugInfoProvider.cpp + ImageDebugLoadingStateHandler.cpp + ImageDebugLoadingStateHandlerRoster.cpp NoOpStackFrameDebugInfo.cpp SpecificImageDebugInfo.cpp SpecificImageDebugInfoLoadingState.cpp @@ -119,6 +122,9 @@ Application Debugger : StackFrameDebugInfo.cpp TeamDebugInfo.cpp + # debug_info/loading_state_handlers + DwarfLoadingStateHandler.cpp + # debugger_interface DebugEvent.cpp DebuggerInterface.cpp diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp new file mode 100644 index 0000000000..f57cd29491 --- /dev/null +++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "ImageDebugLoadingStateHandler.h" + + +ImageDebugLoadingStateHandler::~ImageDebugLoadingStateHandler() +{ +} diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h new file mode 100644 index 0000000000..24f54f4b87 --- /dev/null +++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h @@ -0,0 +1,30 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef IMAGE_DEBUG_LOADING_STATE_HANDLER_H +#define IMAGE_DEBUG_LOADING_STATE_HANDLER_H + + +#include + + +class SpecificImageDebugInfoLoadingState; +class UserInterface; + + +class ImageDebugLoadingStateHandler : public BReferenceable { +public: + virtual ~ImageDebugLoadingStateHandler(); + + virtual bool SupportsState( + SpecificImageDebugInfoLoadingState* state) + = 0; + + virtual void HandleState( + SpecificImageDebugInfoLoadingState* state, + UserInterface* interface) = 0; +}; + + +#endif // IMAGE_DEBUG_LOADING_STATE_HANDLER_H diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp new file mode 100644 index 0000000000..8745d218cf --- /dev/null +++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "ImageDebugLoadingStateHandlerRoster.h" + +#include + +#include +#include + +#include "DwarfLoadingStateHandler.h" +#include "ImageDebugInfoLoadingState.h" +#include "ImageDebugLoadingStateHandler.h" +#include "SpecificImageDebugInfoLoadingState.h" + + +/*static*/ ImageDebugLoadingStateHandlerRoster* + ImageDebugLoadingStateHandlerRoster::sDefaultInstance = NULL; + + +ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster() + : + fLock("type handler roster") +{ +} + + +ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster() +{ +} + + +/*static*/ ImageDebugLoadingStateHandlerRoster* +ImageDebugLoadingStateHandlerRoster::Default() +{ + return sDefaultInstance; +} + + +/*static*/ status_t +ImageDebugLoadingStateHandlerRoster::CreateDefault() +{ + if (sDefaultInstance != NULL) + return B_OK; + + ImageDebugLoadingStateHandlerRoster* roster + = new(std::nothrow) ImageDebugLoadingStateHandlerRoster; + if (roster == NULL) + return B_NO_MEMORY; + ObjectDeleter rosterDeleter(roster); + + status_t error = roster->Init(); + if (error != B_OK) + return error; + + error = roster->RegisterDefaultHandlers(); + if (error != B_OK) + return error; + + sDefaultInstance = rosterDeleter.Detach(); + return B_OK; +} + + +/*static*/ void +ImageDebugLoadingStateHandlerRoster::DeleteDefault() +{ + ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance; + sDefaultInstance = NULL; + delete roster; +} + + +status_t +ImageDebugLoadingStateHandlerRoster::Init() +{ + return fLock.InitCheck(); +} + + +status_t +ImageDebugLoadingStateHandlerRoster::RegisterDefaultHandlers() +{ + ImageDebugLoadingStateHandler* handler; + BReference handlerReference; + + handler = new(std::nothrow) DwarfLoadingStateHandler(); + if (handler == NULL) + return B_NO_MEMORY; + handlerReference.SetTo(handler, true); + + if (!RegisterHandler(handler)) + return B_NO_MEMORY; + + return B_OK; +} + + +status_t +ImageDebugLoadingStateHandlerRoster::FindStateHandler( + SpecificImageDebugInfoLoadingState* state, + ImageDebugLoadingStateHandler*& _handler) +{ + AutoLocker locker(fLock); + + bool found = false; + ImageDebugLoadingStateHandler* handler = NULL; + for (int32 i = 0; (handler = fStateHandlers.ItemAt(i)); i++) { + if ((found = handler->SupportsState(state))) + break; + } + + if (!found) + return B_ENTRY_NOT_FOUND; + + handler->AcquireReference(); + _handler = handler; + return B_OK; +} + + +bool +ImageDebugLoadingStateHandlerRoster::RegisterHandler( + ImageDebugLoadingStateHandler* handler) +{ + if (!fStateHandlers.AddItem(handler)) + return false; + + handler->AcquireReference(); + return true; +} + + +void +ImageDebugLoadingStateHandlerRoster::UnregisterHandler( + ImageDebugLoadingStateHandler* handler) +{ + if (fStateHandlers.RemoveItem(handler)) + handler->ReleaseReference(); +} diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h new file mode 100644 index 0000000000..6731ae22c2 --- /dev/null +++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h @@ -0,0 +1,56 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H +#define IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H + + +#include +#include + + +class ImageDebugLoadingStateHandler; +class SpecificImageDebugInfoLoadingState; + + +typedef BObjectList LoadingStateHandlerList; + + +class ImageDebugLoadingStateHandlerRoster { +public: + ImageDebugLoadingStateHandlerRoster(); + ~ImageDebugLoadingStateHandlerRoster(); + + static ImageDebugLoadingStateHandlerRoster* + Default(); + static status_t CreateDefault(); + static void DeleteDefault(); + + status_t Init(); + status_t RegisterDefaultHandlers(); + + status_t FindStateHandler( + SpecificImageDebugInfoLoadingState* state, + ImageDebugLoadingStateHandler*& + _handler); + // returns a reference + + bool RegisterHandler( + ImageDebugLoadingStateHandler* + handler); + void UnregisterHandler( + ImageDebugLoadingStateHandler* + handler); + +private: + BLocker fLock; + LoadingStateHandlerList + fStateHandlers; + static ImageDebugLoadingStateHandlerRoster* + sDefaultInstance; +}; + + +#endif // IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H + diff --git a/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp new file mode 100644 index 0000000000..21b58b5dca --- /dev/null +++ b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "DwarfLoadingStateHandler.h" + +#include +#include + +#include "DwarfFile.h" +#include "DwarfImageDebugInfoLoadingState.h" +#include "Tracing.h" +#include "UserInterface.h" + + +DwarfLoadingStateHandler::DwarfLoadingStateHandler() + : + ImageDebugLoadingStateHandler() +{ +} + + +DwarfLoadingStateHandler::~DwarfLoadingStateHandler() +{ +} + + +bool +DwarfLoadingStateHandler::SupportsState( + SpecificImageDebugInfoLoadingState* state) +{ + return dynamic_cast(state) != NULL; +} + + +void +DwarfLoadingStateHandler::HandleState( + SpecificImageDebugInfoLoadingState* state, UserInterface* interface) +{ + DwarfImageDebugInfoLoadingState* dwarfState + = dynamic_cast(state); + + if (dwarfState == NULL) { + ERROR("DwarfLoadingStateHandler::HandleState() passed " + "non-dwarf state object %p.", state); + return; + } + + DwarfFileLoadingState& fileState = dwarfState->GetFileState(); + + // TODO: if the image in question is packaged, query if it has a + // corresponding debug info package. If so, offer to install it and + // then locate the file automatically rather than forcing the user to + // locate the file manually. + BString message; + message.SetToFormat("The debug information file '%s' for image '%s' is " + "missing. Please locate it if possible.", + fileState.externalInfoFileName.String(), fileState.dwarfFile->Name()); + int32 choice = interface->SynchronouslyAskUser("Debug info missing", + message.String(), "Locate", "Skip", NULL); + + if (choice == 0) { + entry_ref ref; + interface->SynchronouslyAskUserForFile(&ref); + BPath path(&ref); + if (path.InitCheck() == B_OK) + fileState.locatedExternalInfoPath = path.Path(); + } + + fileState.state = DWARF_FILE_LOADING_STATE_USER_INPUT_PROVIDED; +} diff --git a/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h new file mode 100644 index 0000000000..18bbb000a7 --- /dev/null +++ b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h @@ -0,0 +1,27 @@ +/* + * Copyright 2014, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef DWARF_LOADING_STATE_HANDLER +#define DWARF_LOADING_STATE_HANDLER + + +#include "ImageDebugLoadingStateHandler.h" + + +class DwarfLoadingStateHandler : public ImageDebugLoadingStateHandler { +public: + DwarfLoadingStateHandler(); + virtual ~DwarfLoadingStateHandler(); + + virtual bool SupportsState( + SpecificImageDebugInfoLoadingState* state); + + virtual void HandleState( + SpecificImageDebugInfoLoadingState* state, + UserInterface* interface); + +}; + + +#endif // DWARF_LOADING_STATE_HANDLER_H