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