xref: /haiku/headers/os/kernel/debugger.h (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 /*
2  * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _DEBUGGER_H
6 #define _DEBUGGER_H
7 
8 #include <signal.h>
9 
10 #include <image.h>
11 #include <OS.h>
12 
13 // include architecture specific definitions
14 #ifdef __INTEL__
15 	#include <arch/x86/arch_debugger.h>
16 #elif __POWERPC__
17 	#include <arch/ppc/arch_debugger.h>
18 #endif
19 
20 typedef struct debug_cpu_state debug_cpu_state;
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 extern status_t	install_default_debugger(port_id debuggerPort);
27 extern port_id	install_team_debugger(team_id team, port_id debuggerPort);
28 extern status_t	remove_team_debugger(team_id team);
29 extern status_t	debug_thread(thread_id thread);
30 extern void		wait_for_debugger(void);
31 
32 // team debugging flags
33 enum {
34 	// event mask: If a flag is set, any of the team's threads will stop when
35 	// the respective event occurs. All flags are enabled by default. Always
36 	// enabled are debugger() calls and hardware exceptions, as well as the
37 	// deletion of the debugged team.
38 	B_TEAM_DEBUG_SIGNALS						= 0x00010000,
39 	B_TEAM_DEBUG_PRE_SYSCALL					= 0x00020000,
40 	B_TEAM_DEBUG_POST_SYSCALL					= 0x00040000,
41 	B_TEAM_DEBUG_TEAM_CREATION					= 0x00080000,
42 	B_TEAM_DEBUG_THREADS						= 0x00100000,
43 	B_TEAM_DEBUG_IMAGES							= 0x00200000,
44 
45 	// new thread handling
46 	B_TEAM_DEBUG_STOP_NEW_THREADS				= 0x01000000,
47 
48 	B_TEAM_DEBUG_USER_FLAG_MASK					= 0xffff0000,
49 };
50 
51 // per-thread debugging flags
52 enum {
53 	// event mask: If a flag is set, the thread will stop when the respective
54 	// event occurs. If there is a corresponding team flag, it is sufficient,
55 	// if either is set. Per default none of the flags is set.
56 	B_THREAD_DEBUG_PRE_SYSCALL					= 0x00010000,
57 	B_THREAD_DEBUG_POST_SYSCALL					= 0x00020000,
58 
59 	// child thread handling
60 	B_THREAD_DEBUG_STOP_CHILD_THREADS			= 0x00100000,
61 	B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS	= 0x00200000,
62 
63 	B_THREAD_DEBUG_USER_FLAG_MASK				= 0xffff0000,
64 };
65 
66 // in case of a B_EXCEPTION_OCCURRED event: the type of the exception
67 typedef enum {
68 	B_NON_MASKABLE_INTERRUPT	= 0,
69 	B_MACHINE_CHECK_EXCEPTION,
70 	B_SEGMENT_VIOLATION,
71 	B_ALIGNMENT_EXCEPTION,
72 	B_DIVIDE_ERROR,
73 	B_OVERFLOW_EXCEPTION,
74 	B_BOUNDS_CHECK_EXCEPTION,
75 	B_INVALID_OPCODE_EXCEPTION,
76 	B_SEGMENT_NOT_PRESENT,
77 	B_STACK_FAULT,
78 	B_GENERAL_PROTECTION_FAULT,
79 	B_FLOATING_POINT_EXCEPTION,
80 } debug_exception_type;
81 
82 // Value indicating how a stopped thread shall continue.
83 enum {
84 	B_THREAD_DEBUG_HANDLE_EVENT = 0,	// handle the event normally
85 										// (e.g. a signal is delivered, a
86 										// CPU fault kills the team,...)
87 	B_THREAD_DEBUG_IGNORE_EVENT,		// ignore the event and continue as if
88 										// it didn't occur (e.g. a signal or
89 										// a CPU fault will be ignored)
90 };
91 
92 // watchpoint types (ToDo: Check PPC support.)
93 enum {
94 	B_DATA_READ_WATCHPOINT = 0,			// !x86
95 	B_DATA_WRITE_WATCHPOINT,
96 	B_DATA_READ_WRITE_WATCHPOINT,
97 };
98 
99 // how to apply signal ignore masks
100 typedef enum {
101 	B_DEBUG_SIGNAL_MASK_AND	= 0,
102 	B_DEBUG_SIGNAL_MASK_OR,
103 	B_DEBUG_SIGNAL_MASK_SET,
104 } debug_signal_mask_op;
105 
106 #define B_DEBUG_SIGNAL_TO_MASK(signal) (1ULL << ((signal) - 1))
107 
108 // maximal number of bytes to read/write via B_DEBUG_MESSAGE_{READ,WRITE]_MEMORY
109 enum {
110 	B_MAX_READ_WRITE_MEMORY_SIZE	= 1024,
111 };
112 
113 // messages to the debug nub thread
114 typedef enum {
115 	B_DEBUG_MESSAGE_READ_MEMORY	= 0,	// read from the team's memory
116 	B_DEBUG_MESSAGE_WRITE_MEMORY,		// write to the team's memory
117 	B_DEBUG_MESSAGE_SET_TEAM_FLAGS,		// set the team's debugging flags
118 	B_DEBUG_MESSAGE_SET_THREAD_FLAGS,	// set a thread's debugging flags
119 	B_DEBUG_MESSAGE_CONTINUE_THREAD,	// continue a stopped thread
120 	B_DEBUG_MESSAGE_SET_CPU_STATE,		// change a stopped thread's CPU state
121 	B_DEBUG_MESSAGE_GET_CPU_STATE,		// get the thread's current CPU state
122 	B_DEBUG_MESSAGE_SET_BREAKPOINT,		// set a breakpoint
123 	B_DEBUG_MESSAGE_CLEAR_BREAKPOINT,	// clear a breakpoint
124 	B_DEBUG_MESSAGE_SET_WATCHPOINT,		// set a watchpoint
125 	B_DEBUG_MESSAGE_CLEAR_WATCHPOINT,	// clear a watchpoint
126 	B_DEBUG_MESSAGE_SET_SIGNAL_MASKS,	// set/get a thread's masks of signals
127 	B_DEBUG_MESSAGE_GET_SIGNAL_MASKS,	//  the debugger is interested in
128 	B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER,	// set/get a thread's signal handler for
129 	B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER,	//  a signal
130 
131 	B_DEBUG_MESSAGE_PREPARE_HANDOVER,	// prepares the debugged team for being
132 										// handed over to another debugger;
133 										// the new debugger can just invoke
134 										// install_team_debugger()
135 } debug_nub_message;
136 
137 // messages sent to the debugger
138 typedef enum {
139 	B_DEBUGGER_MESSAGE_THREAD_DEBUGGED = 0,	// debugger message in reaction to
140 											// an invocation of debug_thread()
141 	B_DEBUGGER_MESSAGE_DEBUGGER_CALL,		// thread called debugger()
142 	B_DEBUGGER_MESSAGE_BREAKPOINT_HIT,		// thread hit a breakpoint
143 	B_DEBUGGER_MESSAGE_WATCHPOINT_HIT,		// thread hit a watchpoint
144 	B_DEBUGGER_MESSAGE_SINGLE_STEP,			// thread was single-stepped
145 	B_DEBUGGER_MESSAGE_PRE_SYSCALL,			// begin of a syscall
146 	B_DEBUGGER_MESSAGE_POST_SYSCALL,		// end of a syscall
147 	B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED,		// thread received a signal
148 	B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED,	// an exception occurred
149 	B_DEBUGGER_MESSAGE_TEAM_CREATED,		// the debugged team created a new
150 											// one
151 	B_DEBUGGER_MESSAGE_TEAM_DELETED,		// the debugged team is gone
152 	B_DEBUGGER_MESSAGE_THREAD_CREATED,		// a thread has been created
153 	B_DEBUGGER_MESSAGE_THREAD_DELETED,		// a thread has been deleted
154 	B_DEBUGGER_MESSAGE_IMAGE_CREATED,		// an image has been created
155 	B_DEBUGGER_MESSAGE_IMAGE_DELETED,		// an image has been deleted
156 
157 	B_DEBUGGER_MESSAGE_HANDED_OVER,			// the debugged team has been
158 											// handed over to another debugger
159 } debug_debugger_message;
160 
161 
162 // #pragma mark -
163 // #pragma mark ----- messages to the debug nub thread -----
164 
165 // B_DEBUG_MESSAGE_READ_MEMORY
166 
167 typedef struct {
168 	port_id		reply_port;		// port to send the reply to
169 	void		*address;		// address from which to read
170 	int32		size;			// number of bytes to read
171 } debug_nub_read_memory;
172 
173 typedef struct {
174 	status_t	error;			// B_OK, if reading went fine
175 	int32		size;			// the number of bytes actually read
176 								// > 0, iff error == B_OK
177 	char		data[B_MAX_READ_WRITE_MEMORY_SIZE];
178 								// the read data
179 } debug_nub_read_memory_reply;
180 
181 // B_DEBUG_MESSAGE_WRITE_MEMORY
182 
183 typedef struct {
184 	port_id		reply_port;		// port to send the reply to
185 	void		*address;		// address to which to write
186 	int32		size;			// number of bytes to write
187 	char		data[B_MAX_READ_WRITE_MEMORY_SIZE];
188 								// data to write
189 } debug_nub_write_memory;
190 
191 typedef struct {
192 	status_t	error;			// B_OK, if writing went fine
193 	int32		size;			// the number of bytes actually written
194 } debug_nub_write_memory_reply;
195 
196 // B_DEBUG_MESSAGE_SET_TEAM_FLAGS
197 
198 typedef struct {
199 	int32		flags;			// the new team debugging flags
200 } debug_nub_set_team_flags;
201 
202 // B_DEBUG_MESSAGE_SET_THREAD_FLAGS
203 
204 typedef struct {
205 	thread_id	thread;			// the thread
206 	int32		flags;			// the new thread debugging flags
207 } debug_nub_set_thread_flags;
208 
209 // B_DEBUG_MESSAGE_CONTINUE_THREAD
210 
211 typedef struct {
212 	thread_id	thread;			// the thread
213 	uint32		handle_event;	// how to handle the occurred event
214 	bool		single_step;	// true == single step, false == run full speed
215 } debug_nub_continue_thread;
216 
217 // B_DEBUG_MESSAGE_SET_CPU_STATE
218 
219 typedef struct {
220 	thread_id			thread;				// the thread
221 	debug_cpu_state		cpu_state;			// the new CPU state
222 } debug_nub_set_cpu_state;
223 
224 // B_DEBUG_MESSAGE_GET_CPU_STATE
225 
226 typedef struct {
227 	port_id					reply_port;		// port to send the reply to
228 	thread_id				thread;			// the thread
229 } debug_nub_get_cpu_state;
230 
231 typedef struct {
232 	status_t				error;		// != B_OK, if something went wrong
233 										// (bad thread ID, thread not stopped)
234 	debug_debugger_message	message;	// the reason why the thread stopped
235 	debug_cpu_state			cpu_state;	// the thread's CPU state
236 } debug_nub_get_cpu_state_reply;
237 
238 // B_DEBUG_MESSAGE_SET_BREAKPOINT
239 
240 typedef struct {
241 	port_id		reply_port;		// port to send the reply to
242 	void		*address;		// breakpoint address
243 } debug_nub_set_breakpoint;
244 
245 typedef struct {
246 	status_t	error;			// B_OK, if the breakpoint has been set
247 								// successfully
248 } debug_nub_set_breakpoint_reply;
249 
250 // B_DEBUG_MESSAGE_CLEAR_BREAKPOINT
251 
252 typedef struct {
253 	void		*address;		// breakpoint address
254 } debug_nub_clear_breakpoint;
255 
256 // B_DEBUG_MESSAGE_SET_WATCHPOINT
257 
258 typedef struct {
259 	port_id		reply_port;		// port to send the reply to
260 	void		*address;		// watchpoint address
261 	uint32		type;			// watchpoint type (see type constants above)
262 	int32		length;			// number of bytes to watch (typically 1, 2,
263 								// 4); architecture specific alignment
264 								// restrictions apply.
265 } debug_nub_set_watchpoint;
266 
267 typedef struct {
268 	status_t	error;			// B_OK, if the watchpoint has been set
269 								// successfully
270 } debug_nub_set_watchpoint_reply;
271 
272 // B_DEBUG_MESSAGE_CLEAR_WATCHPOINT
273 
274 typedef struct {
275 	void		*address;		// watchpoint address
276 } debug_nub_clear_watchpoint;
277 
278 // B_DEBUG_MESSAGE_SET_SIGNAL_MASKS
279 
280 typedef struct {
281 	thread_id				thread;				// the thread
282 	uint64					ignore_mask;		// the mask for signals the
283 												// debugger wishes not to be
284 												// notified of
285 	uint64					ignore_once_mask;	// the mask for signals the
286 												// debugger wishes not to be
287 												// notified of when they next
288 												// occur
289 	debug_signal_mask_op	ignore_op;			// what to do with ignore_mask
290 	debug_signal_mask_op	ignore_once_op;		// what to do with
291 												// ignore_once_mask
292 } debug_nub_set_signal_masks;
293 
294 // B_DEBUG_MESSAGE_GET_SIGNAL_MASKS
295 
296 typedef struct {
297 	port_id		reply_port;			// port to send the reply to
298 	thread_id	thread;				// the thread
299 } debug_nub_get_signal_masks;
300 
301 typedef struct {
302 	status_t	error;				// B_OK, if the thread exists
303 	uint64		ignore_mask;		// the mask for signals the debugger wishes
304 									// not to be notified of
305 	uint64		ignore_once_mask;	// the mask for signals the debugger wishes
306 									// not to be notified of when they next
307 									// occur
308 } debug_nub_get_signal_masks_reply;
309 
310 // B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER
311 
312 typedef struct {
313 	thread_id			thread;		// the thread
314 	int					signal;		// the signal
315 	struct sigaction	handler;	// the new signal handler
316 } debug_nub_set_signal_handler;
317 
318 // B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER
319 
320 typedef struct {
321 	port_id				reply_port;	// port to send the reply to
322 	thread_id			thread;		// the thread
323 	int					signal;		// the signal
324 } debug_nub_get_signal_handler;
325 
326 typedef struct {
327 	status_t			error;		// B_OK, if the thread exists
328 	struct sigaction	handler;	// the signal handler
329 } debug_nub_get_signal_handler_reply;
330 
331 // B_DEBUG_MESSAGE_PREPARE_HANDOVER
332 
333 // no parameters, no reply
334 
335 // union of all messages structures sent to the debug nub thread
336 typedef union {
337 	debug_nub_read_memory			read_memory;
338 	debug_nub_write_memory			write_memory;
339 	debug_nub_set_team_flags		set_team_flags;
340 	debug_nub_set_thread_flags		set_thread_flags;
341 	debug_nub_continue_thread		continue_thread;
342 	debug_nub_set_cpu_state			set_cpu_state;
343 	debug_nub_get_cpu_state			get_cpu_state;
344 	debug_nub_set_breakpoint		set_breakpoint;
345 	debug_nub_clear_breakpoint		clear_breakpoint;
346 	debug_nub_set_watchpoint		set_watchpoint;
347 	debug_nub_clear_watchpoint		clear_watchpoint;
348 	debug_nub_set_signal_masks		set_signal_masks;
349 	debug_nub_get_signal_masks		get_signal_masks;
350 	debug_nub_set_signal_handler	set_signal_handler;
351 	debug_nub_get_signal_handler	get_signal_handler;
352 } debug_nub_message_data;
353 
354 
355 // #pragma mark -
356 // #pragma mark ----- messages to the debugger -----
357 
358 // first member of all debugger messages -- not a message by itself
359 typedef struct {
360 	thread_id	thread;			// the thread being the event origin
361 	team_id		team;			// the thread's team
362 	port_id		nub_port;		// port to debug nub for this team (only set
363 								// for synchronous messages)
364 } debug_origin;
365 
366 // B_DEBUGGER_MESSAGE_THREAD_DEBUGGED
367 
368 typedef struct {
369 	debug_origin		origin;
370 } debug_thread_debugged;
371 
372 // B_DEBUGGER_MESSAGE_DEBUGGER_CALL
373 
374 typedef struct {
375 	debug_origin		origin;
376 	void				*message;	// address of the message passed to
377 									// debugger()
378 } debug_debugger_call;
379 
380 // B_DEBUGGER_MESSAGE_BREAKPOINT_HIT
381 
382 typedef struct {
383 	debug_origin		origin;
384 	debug_cpu_state		cpu_state;	// cpu state
385 	bool				software;	// true, if the is a software breakpoint
386 									// (i.e. caused by a respective trap
387 									// instruction)
388 } debug_breakpoint_hit;
389 
390 // B_DEBUGGER_MESSAGE_WATCHPOINT_HIT
391 
392 typedef struct {
393 	debug_origin		origin;
394 	debug_cpu_state		cpu_state;	// cpu state
395 } debug_watchpoint_hit;
396 
397 // B_DEBUGGER_MESSAGE_SINGLE_STEP
398 
399 typedef struct {
400 	debug_origin		origin;
401 	debug_cpu_state		cpu_state;	// cpu state
402 } debug_single_step;
403 
404 // B_DEBUGGER_MESSAGE_PRE_SYSCALL
405 
406 typedef struct {
407 	debug_origin	origin;
408 	uint32			syscall;		// the syscall number
409 	uint32			args[16];		// syscall arguments
410 } debug_pre_syscall;
411 
412 // B_DEBUGGER_MESSAGE_POST_SYSCALL
413 
414 typedef struct {
415 	debug_origin	origin;
416 	bigtime_t		start_time;		// time of syscall start
417 	bigtime_t		end_time;		// time of syscall completion
418 	uint64			return_value;	// the syscall's return value
419 	uint32			syscall;		// the syscall number
420 	uint32			args[16];		// syscall arguments
421 } debug_post_syscall;
422 
423 // B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED
424 
425 typedef struct {
426 	debug_origin		origin;
427 	int					signal;		// the signal
428 	struct sigaction	handler;	// the signal handler
429 	bool				deadly;		// true, if handling the signal will kill
430 									// the team
431 } debug_signal_received;
432 
433 // B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED
434 
435 typedef struct {
436 	debug_origin			origin;
437 	debug_exception_type	exception;		// the exception
438 	int						signal;			// the signal that will be sent,
439 											// when the thread continues
440 											// normally
441 } debug_exception_occurred;
442 
443 // B_DEBUGGER_MESSAGE_TEAM_CREATED
444 
445 typedef struct {
446 	debug_origin	origin;
447 	team_id			new_team;		// the newly created team
448 } debug_team_created;
449 
450 // B_DEBUGGER_MESSAGE_TEAM_DELETED
451 
452 typedef struct {
453 	debug_origin	origin;			// thread is < 0, team is the deleted team
454 									// (asynchronous message)
455 } debug_team_deleted;
456 
457 // B_DEBUGGER_MESSAGE_THREAD_CREATED
458 
459 typedef struct {
460 	debug_origin	origin;			// the thread that created the new thread
461 	team_id			new_thread;		// the newly created thread
462 } debug_thread_created;
463 
464 // B_DEBUGGER_MESSAGE_THREAD_DELETED
465 
466 typedef struct {
467 	debug_origin	origin;			// the deleted thread (asynchronous message)
468 } debug_thread_deleted;
469 
470 // B_DEBUGGER_MESSAGE_IMAGE_CREATED
471 
472 typedef struct {
473 	debug_origin	origin;
474 	image_info		info;			// info for the image
475 } debug_image_created;
476 
477 // B_DEBUGGER_MESSAGE_IMAGE_DELETED
478 
479 typedef struct {
480 	debug_origin	origin;
481 	image_info		info;			// info for the image
482 } debug_image_deleted;
483 
484 // B_DEBUGGER_MESSAGE_HANDED_OVER
485 
486 typedef struct {
487 	debug_origin	origin;			// thread is < 0, team is the deleted team
488 									// (asynchronous message)
489 	team_id			debugger;		// the new debugger
490 	port_id			debugger_port;	// the port the new debugger uses
491 } debug_handed_over;
492 
493 // union of all messages structures sent to the debugger
494 typedef union {
495 	debug_thread_debugged			thread_debugged;
496 	debug_debugger_call				debugger_call;
497 	debug_breakpoint_hit			breakpoint_hit;
498 	debug_watchpoint_hit			watchpoint_hit;
499 	debug_single_step				single_step;
500 	debug_pre_syscall				pre_syscall;
501 	debug_post_syscall				post_syscall;
502 	debug_signal_received			signal_received;
503 	debug_exception_occurred		exception_occurred;
504 	debug_team_created				team_created;
505 	debug_team_deleted				team_deleted;
506 	debug_thread_created			thread_created;
507 	debug_thread_deleted			thread_deleted;
508 	debug_image_created				image_created;
509 	debug_image_deleted				image_deleted;
510 	debug_handed_over				handed_over;
511 
512 	debug_origin					origin;	// for convenience (no real message)
513 } debug_debugger_message_data;
514 
515 
516 extern void get_debug_message_string(debug_debugger_message message,
517 		char *buffer, int32 bufferSize);
518 extern void get_debug_exception_string(debug_exception_type exception,
519 		char *buffer, int32 bufferSize);
520 
521 
522 #ifdef __cplusplus
523 }	// extern "C"
524 #endif
525 
526 #endif	// _DEBUGGER_H
527