xref: /haiku/headers/private/debugger/controllers/TeamDebugger.h (revision 05fc1277c47440dc36134816d70e5723c99cfcd2)
1fce4895dSRene Gollent /*
2fce4895dSRene Gollent  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3fce4895dSRene Gollent  * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
4fce4895dSRene Gollent  * Distributed under the terms of the MIT License.
5fce4895dSRene Gollent  */
6fce4895dSRene Gollent #ifndef TEAM_DEBUGGER_H
7fce4895dSRene Gollent #define TEAM_DEBUGGER_H
8fce4895dSRene Gollent 
9fce4895dSRene Gollent 
10fce4895dSRene Gollent #include <debugger.h>
11fce4895dSRene Gollent #include <Looper.h>
12fce4895dSRene Gollent 
13fce4895dSRene Gollent #include "Team.h"
14fce4895dSRene Gollent #include "TeamSettings.h"
15fce4895dSRene Gollent #include "ThreadHandler.h"
16fce4895dSRene Gollent #include "UserInterface.h"
17fce4895dSRene Gollent #include "util/Worker.h"
18fce4895dSRene Gollent 
19fce4895dSRene Gollent 
20fce4895dSRene Gollent class DebugEvent;
21fce4895dSRene Gollent class DebuggerInterface;
22fce4895dSRene Gollent class DebugReportGenerator;
23fce4895dSRene Gollent class FileManager;
24fce4895dSRene Gollent class ImageCreatedEvent;
25fce4895dSRene Gollent class ImageDebugInfoLoadingState;
26fce4895dSRene Gollent class ImageDeletedEvent;
27fce4895dSRene Gollent class PostSyscallEvent;
28fce4895dSRene Gollent class SettingsManager;
29fce4895dSRene Gollent class TeamDebugInfo;
30fce4895dSRene Gollent class TeamDeletedEvent;
31fce4895dSRene Gollent class TeamExecEvent;
32fce4895dSRene Gollent class TeamMemoryBlockManager;
33fce4895dSRene Gollent class Thread;
34fce4895dSRene Gollent class ThreadCreatedEvent;
35fce4895dSRene Gollent class ThreadDeletedEvent;
36fce4895dSRene Gollent class ThreadRenamedEvent;
37fce4895dSRene Gollent class ThreadPriorityChangedEvent;
38fce4895dSRene Gollent class WatchpointManager;
39fce4895dSRene Gollent 
40fce4895dSRene Gollent 
41fce4895dSRene Gollent class TeamDebugger : public BLooper, private UserInterfaceListener,
42fce4895dSRene Gollent 	private JobListener, private Team::Listener {
43fce4895dSRene Gollent public:
44fce4895dSRene Gollent 	class Listener;
45fce4895dSRene Gollent 
46fce4895dSRene Gollent public:
47fce4895dSRene Gollent 								TeamDebugger(Listener* listener,
48fce4895dSRene Gollent 									UserInterface* userInterface,
49fce4895dSRene Gollent 									SettingsManager* settingsManager);
50fce4895dSRene Gollent 								~TeamDebugger();
51fce4895dSRene Gollent 
52fce4895dSRene Gollent 			status_t			Init(DebuggerInterface* interface,
53fce4895dSRene Gollent 									thread_id threadID, int argc,
54fce4895dSRene Gollent 									const char* const* argv,
55fce4895dSRene Gollent 									bool stopInMain);
56fce4895dSRene Gollent 
57fce4895dSRene Gollent 			void				Activate();
58fce4895dSRene Gollent 
TeamID()59fce4895dSRene Gollent 			team_id				TeamID() const	{ return fTeamID; }
60fce4895dSRene Gollent 
IsPostMortem()61fce4895dSRene Gollent 			bool				IsPostMortem() const { return fIsPostMortem; }
62fce4895dSRene Gollent 
ArgumentCount()63fce4895dSRene Gollent 			int					ArgumentCount() const
64fce4895dSRene Gollent 									{ return fCommandLineArgc; }
Arguments()65fce4895dSRene Gollent 			const char**		Arguments() const
66fce4895dSRene Gollent 									{ return fCommandLineArgv; }
GetSettingsManager()67fce4895dSRene Gollent 			SettingsManager*	GetSettingsManager() const
68fce4895dSRene Gollent 									{ return fSettingsManager; }
GetUserInterface()69*05fc1277SRene Gollent 			UserInterface*		GetUserInterface() const
70*05fc1277SRene Gollent 									{ return fUserInterface; }
71fce4895dSRene Gollent 
72fce4895dSRene Gollent 	virtual	void				MessageReceived(BMessage* message);
73fce4895dSRene Gollent 
74fce4895dSRene Gollent private:
75fce4895dSRene Gollent 	// UserInterfaceListener
76fce4895dSRene Gollent 	virtual	void				FunctionSourceCodeRequested(
77fce4895dSRene Gollent 									FunctionInstance* function,
78fce4895dSRene Gollent 									bool forceDisassembly = false);
79fce4895dSRene Gollent 	virtual void				SourceEntryLocateRequested(
80fce4895dSRene Gollent 									const char* sourcePath,
81fce4895dSRene Gollent 									const char* locatedPath);
82fce4895dSRene Gollent 	virtual void				SourceEntryInvalidateRequested(
83fce4895dSRene Gollent 									LocatableFile* sourceFile);
84fce4895dSRene Gollent 	virtual	void				ImageDebugInfoRequested(Image* image);
85fce4895dSRene Gollent 	virtual	void				ValueNodeValueRequested(CpuState* cpuState,
86fce4895dSRene Gollent 									ValueNodeContainer* container,
87fce4895dSRene Gollent 									ValueNode* valueNode);
88fce4895dSRene Gollent 	virtual	void				ValueNodeWriteRequested(ValueNode* node,
89fce4895dSRene Gollent 									CpuState* state,
90fce4895dSRene Gollent 									Value* newValue);
91fce4895dSRene Gollent 	virtual	void				ThreadActionRequested(thread_id threadID,
92fce4895dSRene Gollent 									uint32 action, target_addr_t address);
93fce4895dSRene Gollent 
94fce4895dSRene Gollent 	virtual	void				SetBreakpointRequested(target_addr_t address,
95fce4895dSRene Gollent 									bool enabled, bool hidden = false);
96fce4895dSRene Gollent 	virtual	void				SetBreakpointEnabledRequested(
97fce4895dSRene Gollent 									UserBreakpoint* breakpoint,
98fce4895dSRene Gollent 									bool enabled);
99fce4895dSRene Gollent 	virtual	void				SetBreakpointConditionRequested(
100fce4895dSRene Gollent 									UserBreakpoint* breakpoint,
101fce4895dSRene Gollent 									const char* condition);
102fce4895dSRene Gollent 	virtual	void				ClearBreakpointConditionRequested(
103fce4895dSRene Gollent 									UserBreakpoint* breakpoint);
104fce4895dSRene Gollent 	virtual	void				ClearBreakpointRequested(target_addr_t address);
105fce4895dSRene Gollent 	virtual	void				ClearBreakpointRequested(
106fce4895dSRene Gollent 									UserBreakpoint* breakpoint);
107fce4895dSRene Gollent 
108fce4895dSRene Gollent 	virtual	void				SetStopOnImageLoadRequested(bool enabled,
109fce4895dSRene Gollent 									bool useImageNames);
110fce4895dSRene Gollent 	virtual	void				AddStopImageNameRequested(
111fce4895dSRene Gollent 									const char* name);
112fce4895dSRene Gollent 	virtual	void				RemoveStopImageNameRequested(
113fce4895dSRene Gollent 									const char* name);
114fce4895dSRene Gollent 
115fce4895dSRene Gollent 	virtual	void				SetDefaultSignalDispositionRequested(
116fce4895dSRene Gollent 									int32 disposition);
117fce4895dSRene Gollent 	virtual	void				SetCustomSignalDispositionRequested(
118fce4895dSRene Gollent 									int32 signal, int32 disposition);
119fce4895dSRene Gollent 	virtual	void				RemoveCustomSignalDispositionRequested(
120fce4895dSRene Gollent 									int32 signal);
121fce4895dSRene Gollent 
122fce4895dSRene Gollent 	virtual	void				SetWatchpointRequested(target_addr_t address,
123fce4895dSRene Gollent 									uint32 type, int32 length, bool enabled);
124fce4895dSRene Gollent 	virtual	void				SetWatchpointEnabledRequested(
125fce4895dSRene Gollent 									Watchpoint *watchpoint, bool enabled);
126fce4895dSRene Gollent 	virtual	void				ClearWatchpointRequested(target_addr_t address);
127fce4895dSRene Gollent 	virtual	void				ClearWatchpointRequested(
128fce4895dSRene Gollent 									Watchpoint* breakpoint);
129fce4895dSRene Gollent 
130fce4895dSRene Gollent 	virtual void				InspectRequested(target_addr_t address,
131fce4895dSRene Gollent 									TeamMemoryBlock::Listener* listener);
132fce4895dSRene Gollent 	virtual	void				MemoryWriteRequested(target_addr_t address,
133fce4895dSRene Gollent 									const void* data, target_size_t size);
134fce4895dSRene Gollent 
135fce4895dSRene Gollent 	virtual	void				ExpressionEvaluationRequested(
136fce4895dSRene Gollent 									SourceLanguage* language,
137fce4895dSRene Gollent 									ExpressionInfo* info,
138fce4895dSRene Gollent 									StackFrame* frame = NULL,
139fce4895dSRene Gollent 									::Thread* thread = NULL);
140fce4895dSRene Gollent 
141fce4895dSRene Gollent 	virtual void				DebugReportRequested(entry_ref* targetPath);
142fce4895dSRene Gollent 
143fce4895dSRene Gollent 	virtual	void				WriteCoreFileRequested(entry_ref* targetPath);
144fce4895dSRene Gollent 
145fce4895dSRene Gollent 	virtual	void				TeamRestartRequested();
146fce4895dSRene Gollent 
147fce4895dSRene Gollent 	virtual	bool				UserInterfaceQuitRequested(
148fce4895dSRene Gollent 									QuitOption quitOption);
149fce4895dSRene Gollent 
150fce4895dSRene Gollent 	// JobListener
151fce4895dSRene Gollent 	virtual	void				JobStarted(Job* job);
152fce4895dSRene Gollent 	virtual	void				JobDone(Job* job);
153fce4895dSRene Gollent 	virtual	void				JobWaitingForInput(Job* job);
154fce4895dSRene Gollent 	virtual	void				JobFailed(Job* job);
155fce4895dSRene Gollent 	virtual	void				JobAborted(Job* job);
156fce4895dSRene Gollent 
157fce4895dSRene Gollent 	// Team::Listener
158fce4895dSRene Gollent 	virtual	void				ThreadStateChanged(
159fce4895dSRene Gollent 									const ::Team::ThreadEvent& event);
160fce4895dSRene Gollent 	virtual	void				ThreadCpuStateChanged(
161fce4895dSRene Gollent 									const ::Team::ThreadEvent& event);
162fce4895dSRene Gollent 	virtual	void				ThreadStackTraceChanged(
163fce4895dSRene Gollent 									const ::Team::ThreadEvent& event);
164fce4895dSRene Gollent 	virtual	void				ImageDebugInfoChanged(
165fce4895dSRene Gollent 									const ::Team::ImageEvent& event);
166fce4895dSRene Gollent 
167fce4895dSRene Gollent private:
168fce4895dSRene Gollent 	struct ImageHandler;
169fce4895dSRene Gollent 	struct ImageHandlerHashDefinition;
170fce4895dSRene Gollent 	struct ImageInfoPendingThread;
171fce4895dSRene Gollent 	struct ImageInfoPendingThreadHashDefinition;
172fce4895dSRene Gollent 
173fce4895dSRene Gollent 	typedef BOpenHashTable<ImageHandlerHashDefinition> ImageHandlerTable;
174fce4895dSRene Gollent 	typedef BOpenHashTable<ImageInfoPendingThreadHashDefinition>
175fce4895dSRene Gollent 		ImageInfoPendingThreadTable;
176fce4895dSRene Gollent 
177fce4895dSRene Gollent private:
178fce4895dSRene Gollent 	static	status_t			_DebugEventListenerEntry(void* data);
179fce4895dSRene Gollent 			status_t			_DebugEventListener();
180fce4895dSRene Gollent 
181fce4895dSRene Gollent 			void				_HandleDebuggerMessage(DebugEvent* event);
182fce4895dSRene Gollent 
183fce4895dSRene Gollent 			bool				_HandleTeamDeleted(
184fce4895dSRene Gollent 									TeamDeletedEvent* event);
185fce4895dSRene Gollent 			bool				_HandleThreadCreated(
186fce4895dSRene Gollent 									ThreadCreatedEvent* event);
187fce4895dSRene Gollent 			bool				_HandleThreadRenamed(
188fce4895dSRene Gollent 									ThreadRenamedEvent* event);
189fce4895dSRene Gollent 			bool				_HandleThreadPriorityChanged(
190fce4895dSRene Gollent 									ThreadPriorityChangedEvent* event);
191fce4895dSRene Gollent 			bool				_HandleThreadDeleted(
192fce4895dSRene Gollent 									ThreadDeletedEvent* event);
193fce4895dSRene Gollent 			bool				_HandleImageCreated(
194fce4895dSRene Gollent 									ImageCreatedEvent* event);
195fce4895dSRene Gollent 			bool				_HandleImageDeleted(
196fce4895dSRene Gollent 									ImageDeletedEvent* event);
197fce4895dSRene Gollent 			bool				_HandlePostSyscall(
198fce4895dSRene Gollent 									PostSyscallEvent* event);
199fce4895dSRene Gollent 
200fce4895dSRene Gollent 			void				_PrepareForTeamExec(TeamExecEvent* event);
201fce4895dSRene Gollent 
202fce4895dSRene Gollent 			void				_HandleImageDebugInfoChanged(image_id imageID);
203fce4895dSRene Gollent 			void				_HandleImageFileChanged(image_id imageID);
204fce4895dSRene Gollent 
205fce4895dSRene Gollent 			void				_HandleSetUserBreakpoint(target_addr_t address,
206fce4895dSRene Gollent 									bool enabled, bool hidden);
207fce4895dSRene Gollent 			void				_HandleSetUserBreakpoint(
208fce4895dSRene Gollent 									UserBreakpoint* breakpoint, bool enabled);
209fce4895dSRene Gollent 			void				_HandleClearUserBreakpoint(
210fce4895dSRene Gollent 									target_addr_t address);
211fce4895dSRene Gollent 			void				_HandleClearUserBreakpoint(
212fce4895dSRene Gollent 									UserBreakpoint* breakpoint);
213fce4895dSRene Gollent 
214fce4895dSRene Gollent 			void				_HandleSetWatchpoint(target_addr_t address,
215fce4895dSRene Gollent 									uint32 type, int32 length, 	bool enabled);
216fce4895dSRene Gollent 			void				_HandleSetWatchpoint(
217fce4895dSRene Gollent 									Watchpoint* watchpoint, bool enabled);
218fce4895dSRene Gollent 			void				_HandleClearWatchpoint(	target_addr_t address);
219fce4895dSRene Gollent 			void				_HandleClearWatchpoint(Watchpoint* watchpoint);
220fce4895dSRene Gollent 
221fce4895dSRene Gollent 			void				_HandleInspectAddress(
222fce4895dSRene Gollent 									target_addr_t address,
223fce4895dSRene Gollent 									TeamMemoryBlock::Listener* listener);
224fce4895dSRene Gollent 			void				_HandleWriteMemory(
225fce4895dSRene Gollent 									target_addr_t address, void* data,
226fce4895dSRene Gollent 									target_size_t size);
227fce4895dSRene Gollent 
228fce4895dSRene Gollent 			void				_HandleEvaluateExpression(
229fce4895dSRene Gollent 									SourceLanguage* language,
230fce4895dSRene Gollent 									ExpressionInfo* info,
231fce4895dSRene Gollent 									StackFrame* frame,
232fce4895dSRene Gollent 									::Thread* thread);
233fce4895dSRene Gollent 
234fce4895dSRene Gollent 			void				_HandleWriteCoreFile(const entry_ref& ref);
235fce4895dSRene Gollent 
236fce4895dSRene Gollent 			status_t			_HandleSetArguments(int argc,
237fce4895dSRene Gollent 									const char* const* argv);
238fce4895dSRene Gollent 
239fce4895dSRene Gollent 			void				_HandleDebugInfoJobUserInput(
240fce4895dSRene Gollent 									ImageDebugInfoLoadingState* state);
241fce4895dSRene Gollent 
242fce4895dSRene Gollent 			ThreadHandler*		_GetThreadHandler(thread_id threadID);
243fce4895dSRene Gollent 
244fce4895dSRene Gollent 			status_t			_AddImage(const ImageInfo& imageInfo,
245fce4895dSRene Gollent 									Image** _image = NULL);
246fce4895dSRene Gollent 
247fce4895dSRene Gollent 			void				_LoadSettings();
248fce4895dSRene Gollent 			void				_SaveSettings();
249fce4895dSRene Gollent 
250fce4895dSRene Gollent 			void				_NotifyUser(const char* title,
251fce4895dSRene Gollent 									const char* text,...);
252fce4895dSRene Gollent 
253fce4895dSRene Gollent 			void				_ResetUserBackgroundStatusIfNeeded();
254fce4895dSRene Gollent 									// updates user interface to
255fce4895dSRene Gollent 									// ready/completed message
256fce4895dSRene Gollent 									// for background work status
257fce4895dSRene Gollent 
258fce4895dSRene Gollent private:
259fce4895dSRene Gollent 			Listener*			fListener;
260fce4895dSRene Gollent 			SettingsManager*	fSettingsManager;
261fce4895dSRene Gollent 			::Team*				fTeam;
262fce4895dSRene Gollent 			team_id				fTeamID;
263fce4895dSRene Gollent 			bool				fIsPostMortem;
264fce4895dSRene Gollent 			ThreadHandlerTable	fThreadHandlers;
265fce4895dSRene Gollent 									// protected by the team lock
266fce4895dSRene Gollent 			ImageHandlerTable*	fImageHandlers;
267fce4895dSRene Gollent 			ImageInfoPendingThreadTable* fImageInfoPendingThreads;
268fce4895dSRene Gollent 			DebuggerInterface*	fDebuggerInterface;
269fce4895dSRene Gollent 			TeamDebugInfo*		fTeamDebugInfo;
270fce4895dSRene Gollent 			FileManager*		fFileManager;
271fce4895dSRene Gollent 			Worker*				fWorker;
272fce4895dSRene Gollent 			BreakpointManager*	fBreakpointManager;
273fce4895dSRene Gollent 			WatchpointManager*	fWatchpointManager;
274fce4895dSRene Gollent 			TeamMemoryBlockManager*
275fce4895dSRene Gollent 								fMemoryBlockManager;
276fce4895dSRene Gollent 			DebugReportGenerator*
277fce4895dSRene Gollent 								fReportGenerator;
278fce4895dSRene Gollent 			thread_id			fDebugEventListener;
279fce4895dSRene Gollent 			UserInterface*		fUserInterface;
280fce4895dSRene Gollent 	volatile bool				fTerminating;
281fce4895dSRene Gollent 			bool				fKillTeamOnQuit;
282fce4895dSRene Gollent 			TeamSettings		fTeamSettings;
283fce4895dSRene Gollent 			int					fCommandLineArgc;
284fce4895dSRene Gollent 			const char**		fCommandLineArgv;
285fce4895dSRene Gollent 			bool				fExecPending;
286fce4895dSRene Gollent };
287fce4895dSRene Gollent 
288fce4895dSRene Gollent 
289fce4895dSRene Gollent class TeamDebugger::Listener {
290fce4895dSRene Gollent public:
291fce4895dSRene Gollent 	virtual						~Listener();
292fce4895dSRene Gollent 
293fce4895dSRene Gollent 	virtual void				TeamDebuggerStarted(TeamDebugger* debugger) = 0;
294fce4895dSRene Gollent 	virtual	void				TeamDebuggerRestartRequested(
295fce4895dSRene Gollent 									TeamDebugger* debugger) = 0;
296fce4895dSRene Gollent 	virtual	void				TeamDebuggerQuit(TeamDebugger* debugger) = 0;
297fce4895dSRene Gollent };
298fce4895dSRene Gollent 
299fce4895dSRene Gollent 
300fce4895dSRene Gollent #endif	// TEAM_DEBUGGER_H
301