Debugger: Start adding the groundwork for load state handlers.
Adds abstract class ImageDebugLoadingStateHandler which simply contains two hooks, which allow one to a) ask it if it supports a handling a particular type of loading state, and b) if so, ask it to attempt to handle that case, given the passed in user interface object. Also adds implementing subclass for DwarfImageDebugInfo, currently intended primarily to handle the case of missing external debug information. At present, this just supports prompting the user to find/install the file, but eventually this will be extended to also support automatically installing the corresponding debug information package, if applicable. Finally, adds ImageDebugLoadingStateHandlerRoster, which acts as a front end for matching up a given loading state with the appropriate handler.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
||||
* Copyright 2011-2013, Rene Gollent, [email protected].
|
||||
* Copyright 2011-2014, Rene Gollent, [email protected].
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ImageDebugLoadingStateHandler.h"
|
||||
|
||||
|
||||
ImageDebugLoadingStateHandler::~ImageDebugLoadingStateHandler()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef IMAGE_DEBUG_LOADING_STATE_HANDLER_H
|
||||
#define IMAGE_DEBUG_LOADING_STATE_HANDLER_H
|
||||
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
|
||||
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
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ImageDebugLoadingStateHandlerRoster.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#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<ImageDebugLoadingStateHandlerRoster> 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<ImageDebugLoadingStateHandler> 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<BLocker> 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();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* 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 <Locker.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
|
||||
class ImageDebugLoadingStateHandler;
|
||||
class SpecificImageDebugInfoLoadingState;
|
||||
|
||||
|
||||
typedef BObjectList<ImageDebugLoadingStateHandler> 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
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "DwarfLoadingStateHandler.h"
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
|
||||
#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<DwarfImageDebugInfoLoadingState*>(state) != NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DwarfLoadingStateHandler::HandleState(
|
||||
SpecificImageDebugInfoLoadingState* state, UserInterface* interface)
|
||||
{
|
||||
DwarfImageDebugInfoLoadingState* dwarfState
|
||||
= dynamic_cast<DwarfImageDebugInfoLoadingState*>(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;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* 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
|
||||
Reference in New Issue
Block a user