2009-06-16 04:25:36 +04:00
|
|
|
/*
|
|
|
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2016-03-30 00:44:18 +03:00
|
|
|
* Copyright 2013-2016, Rene Gollent, rene@gollent.com.
|
2009-06-16 04:25:36 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef TEAM_DEBUGGER_H
|
|
|
|
#define TEAM_DEBUGGER_H
|
|
|
|
|
2009-07-22 23:20:06 +04:00
|
|
|
|
2009-06-16 04:25:36 +04:00
|
|
|
#include <debugger.h>
|
2009-06-17 01:47:49 +04:00
|
|
|
#include <Looper.h>
|
|
|
|
|
2009-06-17 17:40:10 +04:00
|
|
|
#include <debug_support.h>
|
2009-06-17 01:47:49 +04:00
|
|
|
|
2009-06-18 21:57:37 +04:00
|
|
|
#include "DebugEvent.h"
|
2014-06-14 04:25:13 +04:00
|
|
|
#include "Jobs.h"
|
2009-06-20 02:13:32 +04:00
|
|
|
#include "Team.h"
|
2011-11-02 23:04:24 +04:00
|
|
|
#include "TeamSettings.h"
|
2009-06-24 05:46:38 +04:00
|
|
|
#include "ThreadHandler.h"
|
2009-10-15 13:47:24 +04:00
|
|
|
#include "UserInterface.h"
|
2009-06-19 19:09:56 +04:00
|
|
|
#include "Worker.h"
|
2009-06-16 04:25:36 +04:00
|
|
|
|
|
|
|
|
2009-06-18 21:57:37 +04:00
|
|
|
class DebuggerInterface;
|
2012-11-18 22:08:38 +04:00
|
|
|
class DebugReportGenerator;
|
2009-07-02 02:09:33 +04:00
|
|
|
class FileManager;
|
2009-07-24 06:35:30 +04:00
|
|
|
class SettingsManager;
|
2009-06-28 01:09:21 +04:00
|
|
|
class TeamDebugInfo;
|
2011-06-10 05:58:39 +04:00
|
|
|
class TeamMemoryBlockManager;
|
2014-10-30 00:32:14 +03:00
|
|
|
class Thread;
|
2012-11-06 14:45:26 +04:00
|
|
|
class WatchpointManager;
|
2009-06-16 04:25:36 +04:00
|
|
|
|
|
|
|
|
2009-10-15 13:47:24 +04:00
|
|
|
class TeamDebugger : public BLooper, private UserInterfaceListener,
|
2015-08-15 23:41:24 +03:00
|
|
|
private JobListener, private Team::Listener {
|
2009-06-16 04:25:36 +04:00
|
|
|
public:
|
2009-06-24 04:16:22 +04:00
|
|
|
class Listener;
|
|
|
|
|
|
|
|
public:
|
2009-07-24 06:35:30 +04:00
|
|
|
TeamDebugger(Listener* listener,
|
2009-10-15 13:47:24 +04:00
|
|
|
UserInterface* userInterface,
|
2009-07-24 06:35:30 +04:00
|
|
|
SettingsManager* settingsManager);
|
2009-06-16 04:25:36 +04:00
|
|
|
~TeamDebugger();
|
|
|
|
|
2016-03-30 00:44:18 +03:00
|
|
|
status_t Init(DebuggerInterface* interface,
|
|
|
|
thread_id threadID, int argc,
|
2013-05-30 03:16:08 +04:00
|
|
|
const char* const* argv,
|
2009-06-17 01:47:49 +04:00
|
|
|
bool stopInMain);
|
2009-06-16 04:25:36 +04:00
|
|
|
|
2010-09-21 19:07:48 +04:00
|
|
|
void Activate();
|
|
|
|
|
2009-06-17 01:47:49 +04:00
|
|
|
team_id TeamID() const { return fTeamID; }
|
|
|
|
|
2016-04-26 04:49:46 +03:00
|
|
|
bool IsPostMortem() const { return fIsPostMortem; }
|
|
|
|
|
2013-05-30 03:16:08 +04:00
|
|
|
int ArgumentCount() const
|
|
|
|
{ return fCommandLineArgc; }
|
|
|
|
const char** Arguments() const
|
|
|
|
{ return fCommandLineArgv; }
|
Debugger: Rework to fully use TargetHostInterface.
Application objects:
- Rework and simplify to take into account that they will no longer be
directly managing the team debugger list. Requests to start a new debugger
are still funnelled through here however, and as such, said requests must
now provide the appropriate target host to start with. Adjust StartTeamWindow
and TeamsWindow accordingly.
- On global init, always create an instance of the local interface.
TargetHostInterface:
- Convert to BLooper and implement TeamDebugger's Listener interface.
TargetHostInterfaces now directly manage their TeamDebugger instances,
and consequently take over the equivalent duties that the main application
previously had.
- Adjust signatures of Attach/CreateTeam to add const. Adjust
LocalTargetHostInterface accordingly.
- Add accessor to determine if a given interface is local or not. Will be
needed for the TeamDebugger's file manager eventually so it knows if it
needs to request remote files if no matching local file is found.
- Add accessor to start a TeamDebugger instance, and corresponding options
structure.
TargetHostInterfaceRoster:
- Minor adjustments to host interface initialization to take into account
needing to start the looper.
- Add accessor for number of running team debuggers, for the main app to
use when deciding to quit.
TeamDebugger:
- Add accessor for SettingsManager. Needed for the case of a restart request,
as the host interfaces do not have direct access to it.
TeamsWindow:
- For now, always grab the local host interface when initializing the window.
Once the remote interface is implemented, this will need to be adjusted, but
the appropriate UI for creating/selecting it is needed first anyways.
With these changes, the main application is fully host-agnostic, and all
management of actual debuggers is delegated to their parent host interfaces.
There still needs to be a listener interface for the host interface and/or
roster though, so that the application can be made aware of when debuggers
quit, as this drives whether it's time to terminate the app or not.
2016-04-21 02:23:01 +03:00
|
|
|
SettingsManager* GetSettingsManager() const
|
|
|
|
{ return fSettingsManager; }
|
2013-05-30 03:16:08 +04:00
|
|
|
|
2009-06-17 01:47:49 +04:00
|
|
|
virtual void MessageReceived(BMessage* message);
|
2009-06-16 04:25:36 +04:00
|
|
|
|
2009-06-24 04:16:22 +04:00
|
|
|
private:
|
2009-10-15 13:47:24 +04:00
|
|
|
// UserInterfaceListener
|
2009-07-19 03:52:16 +04:00
|
|
|
virtual void FunctionSourceCodeRequested(
|
2013-06-22 20:51:27 +04:00
|
|
|
FunctionInstance* function,
|
|
|
|
bool forceDisassembly = false);
|
2010-11-04 00:52:39 +03:00
|
|
|
virtual void SourceEntryLocateRequested(
|
|
|
|
const char* sourcePath,
|
|
|
|
const char* locatedPath);
|
2014-08-29 18:55:45 +04:00
|
|
|
virtual void SourceEntryInvalidateRequested(
|
|
|
|
LocatableFile* sourceFile);
|
2009-07-19 03:52:16 +04:00
|
|
|
virtual void ImageDebugInfoRequested(Image* image);
|
* EnumerationValue -> EnumeratorValue
* Since some types don't have names (e.g. pointer types or anonymous structs or
unions), each type does now also have a unique ID. The global type cache
registers types by ID and by name (if they have one). This fixes clashes of
types with empty names.
* Completely refactored the code dealing with variable values. Formerly we had
Variable and TypeComponentPath to navigate to a component, mapped to a
BVariant representing the value. Now we have:
* Interface Value with various subclasses (BoolValue, IntegerValue, etc.) to
represent a value, with the flexibility for more esoteric values.
* A tree of ValueNode+ValueNodeChild objects to represent the components of a
variable. On top of each ValueNodeChild sits a ValueNode representing the
value of the component, potentially having ValueNodeChild children. This
should allow casting a component value, simply by replacing its ValueNode.
* Interface ValueHandler and various implementations for the different value
types. It is basically a factory for classes allowing to format/display a
value.
* ValueHandlerRoster -- a registry for ValueHandlers, finding the best one
for a given value.
* Interface TypeHandler and various implementions for the different type
kinds (primitive, compound, address, etc.). It is basically a factory for
ValueNodes for that type.
* TypeHandlerRoster -- a registry for TypeHandlers, finding the best one
for a given type.
That's still a bit work in progress. It introduces at least one regression:
The VariablesView doesn't save/restore its state anymore. Will take a while
until that is added back.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33907 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-05 21:15:21 +03:00
|
|
|
virtual void ValueNodeValueRequested(CpuState* cpuState,
|
|
|
|
ValueNodeContainer* container,
|
|
|
|
ValueNode* valueNode);
|
2015-07-24 05:47:08 +03:00
|
|
|
virtual void ValueNodeWriteRequested(ValueNode* node,
|
|
|
|
CpuState* state,
|
|
|
|
Value* newValue);
|
2009-07-19 03:52:16 +04:00
|
|
|
virtual void ThreadActionRequested(thread_id threadID,
|
2013-05-12 07:09:12 +04:00
|
|
|
uint32 action, target_addr_t address);
|
2013-07-07 08:31:22 +04:00
|
|
|
|
2009-06-23 01:51:32 +04:00
|
|
|
virtual void SetBreakpointRequested(target_addr_t address,
|
2013-06-15 22:47:14 +04:00
|
|
|
bool enabled, bool hidden = false);
|
2009-10-14 09:03:00 +04:00
|
|
|
virtual void SetBreakpointEnabledRequested(
|
|
|
|
UserBreakpoint* breakpoint,
|
|
|
|
bool enabled);
|
2014-10-30 21:23:26 +03:00
|
|
|
virtual void SetBreakpointConditionRequested(
|
|
|
|
UserBreakpoint* breakpoint,
|
|
|
|
const char* condition);
|
|
|
|
virtual void ClearBreakpointConditionRequested(
|
|
|
|
UserBreakpoint* breakpoint);
|
2009-06-23 01:51:32 +04:00
|
|
|
virtual void ClearBreakpointRequested(target_addr_t address);
|
2009-10-14 09:03:00 +04:00
|
|
|
virtual void ClearBreakpointRequested(
|
|
|
|
UserBreakpoint* breakpoint);
|
2013-07-07 08:31:22 +04:00
|
|
|
|
|
|
|
virtual void SetStopOnImageLoadRequested(bool enabled,
|
|
|
|
bool useImageNames);
|
|
|
|
virtual void AddStopImageNameRequested(
|
|
|
|
const char* name);
|
|
|
|
virtual void RemoveStopImageNameRequested(
|
|
|
|
const char* name);
|
|
|
|
|
2015-06-30 06:26:08 +03:00
|
|
|
virtual void SetDefaultSignalDispositionRequested(
|
|
|
|
int32 disposition);
|
|
|
|
virtual void SetCustomSignalDispositionRequested(
|
|
|
|
int32 signal, int32 disposition);
|
|
|
|
virtual void RemoveCustomSignalDispositionRequested(
|
|
|
|
int32 signal);
|
|
|
|
|
2012-11-06 14:45:26 +04:00
|
|
|
virtual void SetWatchpointRequested(target_addr_t address,
|
|
|
|
uint32 type, int32 length, bool enabled);
|
|
|
|
virtual void SetWatchpointEnabledRequested(
|
|
|
|
Watchpoint *watchpoint, bool enabled);
|
|
|
|
virtual void ClearWatchpointRequested(target_addr_t address);
|
|
|
|
virtual void ClearWatchpointRequested(
|
|
|
|
Watchpoint* breakpoint);
|
|
|
|
|
2011-06-10 05:58:39 +04:00
|
|
|
virtual void InspectRequested(target_addr_t address,
|
|
|
|
TeamMemoryBlock::Listener* listener);
|
2015-05-23 23:12:43 +03:00
|
|
|
virtual void MemoryWriteRequested(target_addr_t address,
|
|
|
|
const void* data, target_size_t size);
|
2012-11-18 22:08:38 +04:00
|
|
|
|
2014-10-28 22:24:34 +03:00
|
|
|
virtual void ExpressionEvaluationRequested(
|
|
|
|
SourceLanguage* language,
|
2014-11-09 02:20:30 +03:00
|
|
|
ExpressionInfo* info,
|
2014-10-30 00:32:14 +03:00
|
|
|
StackFrame* frame = NULL,
|
|
|
|
::Thread* thread = NULL);
|
2014-10-28 22:24:34 +03:00
|
|
|
|
2012-11-18 22:08:38 +04:00
|
|
|
virtual void DebugReportRequested(entry_ref* targetPath);
|
|
|
|
|
2013-05-30 05:57:48 +04:00
|
|
|
virtual void TeamRestartRequested();
|
|
|
|
|
2012-07-28 01:04:16 +04:00
|
|
|
virtual bool UserInterfaceQuitRequested(
|
|
|
|
QuitOption quitOption);
|
2009-06-19 01:45:14 +04:00
|
|
|
|
2009-06-19 19:09:56 +04:00
|
|
|
// JobListener
|
2015-08-15 23:41:24 +03:00
|
|
|
virtual void JobStarted(Job* job);
|
2009-06-19 19:09:56 +04:00
|
|
|
virtual void JobDone(Job* job);
|
2015-08-15 23:41:24 +03:00
|
|
|
virtual void JobWaitingForInput(Job* job);
|
2009-06-19 19:09:56 +04:00
|
|
|
virtual void JobFailed(Job* job);
|
|
|
|
virtual void JobAborted(Job* job);
|
|
|
|
|
2009-06-20 02:13:32 +04:00
|
|
|
// Team::Listener
|
|
|
|
virtual void ThreadStateChanged(
|
|
|
|
const ::Team::ThreadEvent& event);
|
|
|
|
virtual void ThreadCpuStateChanged(
|
|
|
|
const ::Team::ThreadEvent& event);
|
|
|
|
virtual void ThreadStackTraceChanged(
|
|
|
|
const ::Team::ThreadEvent& event);
|
2009-07-24 06:35:30 +04:00
|
|
|
virtual void ImageDebugInfoChanged(
|
|
|
|
const ::Team::ImageEvent& event);
|
2009-06-20 02:13:32 +04:00
|
|
|
|
2009-07-02 02:09:33 +04:00
|
|
|
private:
|
|
|
|
struct ImageHandler;
|
|
|
|
struct ImageHandlerHashDefinition;
|
2012-11-29 04:11:50 +04:00
|
|
|
struct ImageInfoPendingThread;
|
|
|
|
struct ImageInfoPendingThreadHashDefinition;
|
|
|
|
|
2009-07-27 04:39:12 +04:00
|
|
|
typedef BOpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable;
|
2012-11-29 04:11:50 +04:00
|
|
|
typedef BOpenHashTable<ImageInfoPendingThreadHashDefinition>
|
|
|
|
ImageInfoPendingThreadTable;
|
2009-07-02 02:09:33 +04:00
|
|
|
|
2009-06-16 04:25:36 +04:00
|
|
|
private:
|
|
|
|
static status_t _DebugEventListenerEntry(void* data);
|
|
|
|
status_t _DebugEventListener();
|
|
|
|
|
2009-06-18 21:57:37 +04:00
|
|
|
void _HandleDebuggerMessage(DebugEvent* event);
|
2009-06-16 04:25:36 +04:00
|
|
|
|
2013-04-24 07:05:36 +04:00
|
|
|
bool _HandleTeamDeleted(
|
|
|
|
TeamDeletedEvent* event);
|
2009-06-17 17:40:10 +04:00
|
|
|
bool _HandleThreadCreated(
|
2009-06-18 21:57:37 +04:00
|
|
|
ThreadCreatedEvent* event);
|
2010-12-16 07:19:53 +03:00
|
|
|
bool _HandleThreadRenamed(
|
|
|
|
ThreadRenamedEvent* event);
|
|
|
|
bool _HandleThreadPriorityChanged(
|
|
|
|
ThreadPriorityChangedEvent* event);
|
2009-06-17 17:40:10 +04:00
|
|
|
bool _HandleThreadDeleted(
|
2009-06-18 21:57:37 +04:00
|
|
|
ThreadDeletedEvent* event);
|
2009-06-17 17:40:10 +04:00
|
|
|
bool _HandleImageCreated(
|
2009-06-18 21:57:37 +04:00
|
|
|
ImageCreatedEvent* event);
|
2009-06-17 17:40:10 +04:00
|
|
|
bool _HandleImageDeleted(
|
2009-06-18 21:57:37 +04:00
|
|
|
ImageDeletedEvent* event);
|
2013-06-28 03:40:41 +04:00
|
|
|
bool _HandlePostSyscall(
|
|
|
|
PostSyscallEvent* event);
|
2009-06-17 17:40:10 +04:00
|
|
|
|
2015-07-26 00:18:21 +03:00
|
|
|
void _PrepareForTeamExec(TeamExecEvent* event);
|
|
|
|
|
2009-07-24 06:35:30 +04:00
|
|
|
void _HandleImageDebugInfoChanged(image_id imageID);
|
2009-07-02 02:09:33 +04:00
|
|
|
void _HandleImageFileChanged(image_id imageID);
|
|
|
|
|
2009-06-23 01:51:32 +04:00
|
|
|
void _HandleSetUserBreakpoint(target_addr_t address,
|
2013-06-15 22:47:14 +04:00
|
|
|
bool enabled, bool hidden);
|
2009-10-14 09:03:00 +04:00
|
|
|
void _HandleSetUserBreakpoint(
|
|
|
|
UserBreakpoint* breakpoint, bool enabled);
|
2009-06-23 01:51:32 +04:00
|
|
|
void _HandleClearUserBreakpoint(
|
|
|
|
target_addr_t address);
|
2009-10-14 09:03:00 +04:00
|
|
|
void _HandleClearUserBreakpoint(
|
|
|
|
UserBreakpoint* breakpoint);
|
2009-06-19 01:45:14 +04:00
|
|
|
|
2012-11-06 14:45:26 +04:00
|
|
|
void _HandleSetWatchpoint(target_addr_t address,
|
|
|
|
uint32 type, int32 length, bool enabled);
|
|
|
|
void _HandleSetWatchpoint(
|
|
|
|
Watchpoint* watchpoint, bool enabled);
|
|
|
|
void _HandleClearWatchpoint( target_addr_t address);
|
|
|
|
void _HandleClearWatchpoint(Watchpoint* watchpoint);
|
|
|
|
|
2011-06-10 05:58:39 +04:00
|
|
|
void _HandleInspectAddress(
|
|
|
|
target_addr_t address,
|
|
|
|
TeamMemoryBlock::Listener* listener);
|
2015-05-23 23:12:43 +03:00
|
|
|
void _HandleWriteMemory(
|
|
|
|
target_addr_t address, void* data,
|
|
|
|
target_size_t size);
|
2014-10-28 22:24:34 +03:00
|
|
|
|
|
|
|
void _HandleEvaluateExpression(
|
|
|
|
SourceLanguage* language,
|
2014-11-09 02:20:30 +03:00
|
|
|
ExpressionInfo* info,
|
2014-10-30 00:32:14 +03:00
|
|
|
StackFrame* frame,
|
|
|
|
::Thread* thread);
|
2014-10-28 22:24:34 +03:00
|
|
|
|
2013-05-30 03:16:08 +04:00
|
|
|
status_t _HandleSetArguments(int argc,
|
|
|
|
const char* const* argv);
|
2011-06-10 05:58:39 +04:00
|
|
|
|
2014-06-14 04:25:13 +04:00
|
|
|
void _HandleDebugInfoJobUserInput(
|
|
|
|
ImageDebugInfoLoadingState* state);
|
|
|
|
|
2009-06-24 05:46:38 +04:00
|
|
|
ThreadHandler* _GetThreadHandler(thread_id threadID);
|
2009-06-20 02:13:32 +04:00
|
|
|
|
2009-07-03 18:23:19 +04:00
|
|
|
status_t _AddImage(const ImageInfo& imageInfo,
|
|
|
|
Image** _image = NULL);
|
2009-07-02 02:09:33 +04:00
|
|
|
|
2009-07-24 06:35:30 +04:00
|
|
|
void _LoadSettings();
|
|
|
|
void _SaveSettings();
|
|
|
|
|
2009-06-23 01:51:32 +04:00
|
|
|
void _NotifyUser(const char* title,
|
|
|
|
const char* text,...);
|
|
|
|
|
2015-08-15 03:46:37 +03:00
|
|
|
void _ResetUserBackgroundStatusIfNeeded();
|
|
|
|
// updates user interface to
|
|
|
|
// ready/completed message
|
|
|
|
// for background work status
|
|
|
|
|
2009-06-16 04:25:36 +04:00
|
|
|
private:
|
2009-06-24 04:16:22 +04:00
|
|
|
Listener* fListener;
|
2009-07-24 06:35:30 +04:00
|
|
|
SettingsManager* fSettingsManager;
|
2009-06-17 01:47:49 +04:00
|
|
|
::Team* fTeam;
|
2009-06-16 04:25:36 +04:00
|
|
|
team_id fTeamID;
|
2016-04-26 04:49:46 +03:00
|
|
|
bool fIsPostMortem;
|
2009-06-24 05:46:38 +04:00
|
|
|
ThreadHandlerTable fThreadHandlers;
|
|
|
|
// protected by the team lock
|
2009-07-02 02:09:33 +04:00
|
|
|
ImageHandlerTable* fImageHandlers;
|
2012-11-29 04:11:50 +04:00
|
|
|
ImageInfoPendingThreadTable* fImageInfoPendingThreads;
|
2009-06-18 21:57:37 +04:00
|
|
|
DebuggerInterface* fDebuggerInterface;
|
2009-06-28 01:09:21 +04:00
|
|
|
TeamDebugInfo* fTeamDebugInfo;
|
2009-07-02 02:09:33 +04:00
|
|
|
FileManager* fFileManager;
|
2009-06-19 19:09:56 +04:00
|
|
|
Worker* fWorker;
|
2009-06-26 03:51:09 +04:00
|
|
|
BreakpointManager* fBreakpointManager;
|
2012-11-06 14:45:26 +04:00
|
|
|
WatchpointManager* fWatchpointManager;
|
2011-06-10 05:58:39 +04:00
|
|
|
TeamMemoryBlockManager*
|
|
|
|
fMemoryBlockManager;
|
2012-11-18 22:08:38 +04:00
|
|
|
DebugReportGenerator*
|
|
|
|
fReportGenerator;
|
2009-06-16 04:25:36 +04:00
|
|
|
thread_id fDebugEventListener;
|
2009-10-15 13:47:24 +04:00
|
|
|
UserInterface* fUserInterface;
|
2009-06-16 04:25:36 +04:00
|
|
|
volatile bool fTerminating;
|
2009-06-23 17:09:50 +04:00
|
|
|
bool fKillTeamOnQuit;
|
2011-11-02 23:04:24 +04:00
|
|
|
TeamSettings fTeamSettings;
|
2013-05-30 03:16:08 +04:00
|
|
|
int fCommandLineArgc;
|
|
|
|
const char** fCommandLineArgv;
|
2015-07-26 00:18:21 +03:00
|
|
|
bool fExecPending;
|
2009-06-16 04:25:36 +04:00
|
|
|
};
|
|
|
|
|
2009-06-24 04:16:22 +04:00
|
|
|
|
|
|
|
class TeamDebugger::Listener {
|
|
|
|
public:
|
|
|
|
virtual ~Listener();
|
|
|
|
|
2010-09-21 19:07:48 +04:00
|
|
|
virtual void TeamDebuggerStarted(TeamDebugger* debugger) = 0;
|
2013-05-30 03:16:08 +04:00
|
|
|
virtual void TeamDebuggerRestartRequested(
|
|
|
|
TeamDebugger* debugger) = 0;
|
2009-06-24 04:16:22 +04:00
|
|
|
virtual void TeamDebuggerQuit(TeamDebugger* debugger) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-16 04:25:36 +04:00
|
|
|
#endif // TEAM_DEBUGGER_H
|