2009-06-16 04:25:36 +04:00
|
|
|
/*
|
|
|
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2015-05-23 23:12:43 +03:00
|
|
|
* Copyright 2013-2015, 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();
|
|
|
|
|
2009-06-17 01:47:49 +04:00
|
|
|
status_t Init(team_id teamID, thread_id threadID,
|
2013-05-30 03:16:08 +04:00
|
|
|
int argc,
|
|
|
|
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; }
|
|
|
|
|
2013-05-30 03:16:08 +04:00
|
|
|
int ArgumentCount() const
|
|
|
|
{ return fCommandLineArgc; }
|
|
|
|
const char** Arguments() const
|
|
|
|
{ return fCommandLineArgv; }
|
|
|
|
|
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;
|
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
|