2 * Copyright 2005-2016 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
14 // include architecture specific definitions
15 #include <arch/x86/arch_debugger.h>
16 #include <arch/x86_64/arch_debugger.h>
17 #include <arch/ppc/arch_debugger.h>
18 #include <arch/m68k/arch_debugger.h>
19 #include <arch/mipsel/arch_debugger.h>
20 #include <arch/arm/arch_debugger.h>
24 typedef struct x86_64_debug_cpu_state debug_cpu_state
;
26 typedef struct x86_debug_cpu_state debug_cpu_state
;
28 typedef struct ppc_debug_cpu_state debug_cpu_state
;
30 typedef struct m68k_debug_cpu_state debug_cpu_state
;
32 typedef struct mipsel_debug_cpu_state debug_cpu_state
;
34 typedef struct arm_debug_cpu_state debug_cpu_state
;
36 #error unsupported architecture
44 extern status_t
install_default_debugger(port_id debuggerPort
);
45 extern port_id
install_team_debugger(team_id team
, port_id debuggerPort
);
46 extern status_t
remove_team_debugger(team_id team
);
47 extern status_t
debug_thread(thread_id thread
);
48 extern void wait_for_debugger(void);
50 // EXPERIMENTAL: Self-debugging functions. Will fail when a team debugger is
51 // installed. A breakpoint/watchpoint hit will cause the default debugger to
52 // be installed for the team.
53 extern status_t
set_debugger_breakpoint(void *address
);
54 extern status_t
clear_debugger_breakpoint(void *address
);
55 extern status_t
set_debugger_watchpoint(void *address
, uint32 type
,
57 extern status_t
clear_debugger_watchpoint(void *address
);
60 // team debugging flags
62 // event mask: If a flag is set, any of the team's threads will stop when
63 // the respective event occurs. None of the flags are enabled by default.
64 // Always enabled are debugger() calls and hardware exceptions, as well as
65 // the deletion of the debugged team.
66 B_TEAM_DEBUG_SIGNALS
= 0x00010000,
67 B_TEAM_DEBUG_PRE_SYSCALL
= 0x00020000,
68 B_TEAM_DEBUG_POST_SYSCALL
= 0x00040000,
69 B_TEAM_DEBUG_TEAM_CREATION
= 0x00080000,
70 B_TEAM_DEBUG_THREADS
= 0x00100000,
71 B_TEAM_DEBUG_IMAGES
= 0x00200000,
72 B_TEAM_DEBUG_PREVENT_EXIT
= 0x00400000,
74 // new thread handling
75 B_TEAM_DEBUG_STOP_NEW_THREADS
= 0x01000000,
77 B_TEAM_DEBUG_USER_FLAG_MASK
= 0xffff0000,
80 // per-thread debugging flags
82 // event mask: If a flag is set, the thread will stop when the respective
83 // event occurs. If there is a corresponding team flag, it is sufficient,
84 // if either is set. Per default none of the flags is set.
85 B_THREAD_DEBUG_PRE_SYSCALL
= 0x00010000,
86 B_THREAD_DEBUG_POST_SYSCALL
= 0x00020000,
88 // child thread handling
89 B_THREAD_DEBUG_STOP_CHILD_THREADS
= 0x00100000,
90 B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS
= 0x00200000,
92 B_THREAD_DEBUG_USER_FLAG_MASK
= 0xffff0000,
95 // in case of a B_EXCEPTION_OCCURRED event: the type of the exception
97 B_NON_MASKABLE_INTERRUPT
= 0,
98 B_MACHINE_CHECK_EXCEPTION
,
100 B_ALIGNMENT_EXCEPTION
,
102 B_OVERFLOW_EXCEPTION
,
103 B_BOUNDS_CHECK_EXCEPTION
,
104 B_INVALID_OPCODE_EXCEPTION
,
105 B_SEGMENT_NOT_PRESENT
,
107 B_GENERAL_PROTECTION_FAULT
,
108 B_FLOATING_POINT_EXCEPTION
,
109 } debug_exception_type
;
111 // Value indicating how a stopped thread shall continue.
113 B_THREAD_DEBUG_HANDLE_EVENT
= 0, // handle the event normally
114 // (e.g. a signal is delivered, a
115 // CPU fault kills the team,...)
116 B_THREAD_DEBUG_IGNORE_EVENT
, // ignore the event and continue as if
117 // it didn't occur (e.g. a signal or
118 // a CPU fault will be ignored)
121 // watchpoint types (ToDo: Check PPC support.)
123 B_DATA_READ_WATCHPOINT
= 0, // !x86
124 B_DATA_WRITE_WATCHPOINT
,
125 B_DATA_READ_WRITE_WATCHPOINT
,
128 // how to apply signal ignore masks
130 B_DEBUG_SIGNAL_MASK_AND
= 0,
131 B_DEBUG_SIGNAL_MASK_OR
,
132 B_DEBUG_SIGNAL_MASK_SET
,
133 } debug_signal_mask_op
;
135 #define B_DEBUG_SIGNAL_TO_MASK(signal) (1ULL << ((signal) - 1))
137 // maximal number of bytes to read/write via B_DEBUG_MESSAGE_{READ,WRITE]_MEMORY
139 B_MAX_READ_WRITE_MEMORY_SIZE
= 1024,
142 // messages to the debug nub thread
144 B_DEBUG_MESSAGE_READ_MEMORY
= 0, // read from the team's memory
145 B_DEBUG_MESSAGE_WRITE_MEMORY
, // write to the team's memory
146 B_DEBUG_MESSAGE_SET_TEAM_FLAGS
, // set the team's debugging flags
147 B_DEBUG_MESSAGE_SET_THREAD_FLAGS
, // set a thread's debugging flags
148 B_DEBUG_MESSAGE_CONTINUE_THREAD
, // continue a stopped thread
149 B_DEBUG_MESSAGE_SET_CPU_STATE
, // change a stopped thread's CPU state
150 B_DEBUG_MESSAGE_GET_CPU_STATE
, // get the thread's current CPU state
151 B_DEBUG_MESSAGE_SET_BREAKPOINT
, // set a breakpoint
152 B_DEBUG_MESSAGE_CLEAR_BREAKPOINT
, // clear a breakpoint
153 B_DEBUG_MESSAGE_SET_WATCHPOINT
, // set a watchpoint
154 B_DEBUG_MESSAGE_CLEAR_WATCHPOINT
, // clear a watchpoint
155 B_DEBUG_MESSAGE_SET_SIGNAL_MASKS
, // set/get a thread's masks of signals
156 B_DEBUG_MESSAGE_GET_SIGNAL_MASKS
, // the debugger is interested in
157 B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER
, // set/get the team's signal handler for
158 B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER
, // a signal
160 B_DEBUG_MESSAGE_PREPARE_HANDOVER
, // prepares the debugged team for being
161 // handed over to another debugger;
162 // the new debugger can just invoke
163 // install_team_debugger()
165 B_DEBUG_START_PROFILER
, // start/stop sampling
166 B_DEBUG_STOP_PROFILER
, //
168 B_DEBUG_WRITE_CORE_FILE
// write a core file
171 // messages sent to the debugger
173 B_DEBUGGER_MESSAGE_THREAD_DEBUGGED
= 0, // debugger message in reaction to
174 // an invocation of debug_thread()
175 B_DEBUGGER_MESSAGE_DEBUGGER_CALL
, // thread called debugger()
176 B_DEBUGGER_MESSAGE_BREAKPOINT_HIT
, // thread hit a breakpoint
177 B_DEBUGGER_MESSAGE_WATCHPOINT_HIT
, // thread hit a watchpoint
178 B_DEBUGGER_MESSAGE_SINGLE_STEP
, // thread was single-stepped
179 B_DEBUGGER_MESSAGE_PRE_SYSCALL
, // begin of a syscall
180 B_DEBUGGER_MESSAGE_POST_SYSCALL
, // end of a syscall
181 B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED
, // thread received a signal
182 B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED
, // an exception occurred
183 B_DEBUGGER_MESSAGE_TEAM_CREATED
, // the debugged team created a new
185 B_DEBUGGER_MESSAGE_TEAM_DELETED
, // the debugged team is gone
186 B_DEBUGGER_MESSAGE_TEAM_EXEC
, // the debugged team executes exec()
187 B_DEBUGGER_MESSAGE_THREAD_CREATED
, // a thread has been created
188 B_DEBUGGER_MESSAGE_THREAD_DELETED
, // a thread has been deleted
189 B_DEBUGGER_MESSAGE_IMAGE_CREATED
, // an image has been created
190 B_DEBUGGER_MESSAGE_IMAGE_DELETED
, // an image has been deleted
192 B_DEBUGGER_MESSAGE_PROFILER_UPDATE
, // flush the profiling buffer for a
195 B_DEBUGGER_MESSAGE_HANDED_OVER
, // the debugged team has been
196 // handed over to another debugger,
197 // sent to both debuggers
198 } debug_debugger_message
;
201 // profile events -- when the buffer is in variable stack depth format, a sample
202 // count entry >= B_DEBUG_PROFILE_EVENT_BASE indicates a profile event
204 B_DEBUG_PROFILE_EVENT_BASE
= 0x80000000,
205 B_DEBUG_PROFILE_EVENT_PARAMETER_MASK
= 0x0000ffff,
206 // & with to get the event's parameter count
208 B_DEBUG_PROFILE_IMAGE_EVENT
= 0x80010001
209 // single parameter: the respective image event counter
214 // #pragma mark ----- messages to the debug nub thread -----
216 // B_DEBUG_MESSAGE_READ_MEMORY
219 port_id reply_port
; // port to send the reply to
220 void *address
; // address from which to read
221 int32 size
; // number of bytes to read
222 } debug_nub_read_memory
;
225 status_t error
; // B_OK, if reading went fine
226 int32 size
; // the number of bytes actually read
227 // > 0, iff error == B_OK
228 char data
[B_MAX_READ_WRITE_MEMORY_SIZE
];
230 } debug_nub_read_memory_reply
;
232 // B_DEBUG_MESSAGE_WRITE_MEMORY
235 port_id reply_port
; // port to send the reply to
236 void *address
; // address to which to write
237 int32 size
; // number of bytes to write
238 char data
[B_MAX_READ_WRITE_MEMORY_SIZE
];
240 } debug_nub_write_memory
;
243 status_t error
; // B_OK, if writing went fine
244 int32 size
; // the number of bytes actually written
245 } debug_nub_write_memory_reply
;
247 // B_DEBUG_MESSAGE_SET_TEAM_FLAGS
250 int32 flags
; // the new team debugging flags
251 } debug_nub_set_team_flags
;
253 // B_DEBUG_MESSAGE_SET_THREAD_FLAGS
256 thread_id thread
; // the thread
257 int32 flags
; // the new thread debugging flags
258 } debug_nub_set_thread_flags
;
260 // B_DEBUG_MESSAGE_CONTINUE_THREAD
263 thread_id thread
; // the thread
264 uint32 handle_event
; // how to handle the occurred event
265 bool single_step
; // true == single step, false == run full speed
266 } debug_nub_continue_thread
;
268 // B_DEBUG_MESSAGE_SET_CPU_STATE
271 thread_id thread
; // the thread
272 debug_cpu_state cpu_state
; // the new CPU state
273 } debug_nub_set_cpu_state
;
275 // B_DEBUG_MESSAGE_GET_CPU_STATE
278 port_id reply_port
; // port to send the reply to
279 thread_id thread
; // the thread
280 } debug_nub_get_cpu_state
;
283 status_t error
; // != B_OK, if something went wrong
284 // (bad thread ID, thread not stopped)
285 debug_debugger_message message
; // the reason why the thread stopped
286 debug_cpu_state cpu_state
; // the thread's CPU state
287 } debug_nub_get_cpu_state_reply
;
289 // B_DEBUG_MESSAGE_SET_BREAKPOINT
292 port_id reply_port
; // port to send the reply to
293 void *address
; // breakpoint address
294 } debug_nub_set_breakpoint
;
297 status_t error
; // B_OK, if the breakpoint has been set
299 } debug_nub_set_breakpoint_reply
;
301 // B_DEBUG_MESSAGE_CLEAR_BREAKPOINT
304 void *address
; // breakpoint address
305 } debug_nub_clear_breakpoint
;
307 // B_DEBUG_MESSAGE_SET_WATCHPOINT
310 port_id reply_port
; // port to send the reply to
311 void *address
; // watchpoint address
312 uint32 type
; // watchpoint type (see type constants above)
313 int32 length
; // number of bytes to watch (typically 1, 2,
314 // 4); architecture specific alignment
315 // restrictions apply.
316 } debug_nub_set_watchpoint
;
319 status_t error
; // B_OK, if the watchpoint has been set
321 } debug_nub_set_watchpoint_reply
;
323 // B_DEBUG_MESSAGE_CLEAR_WATCHPOINT
326 void *address
; // watchpoint address
327 } debug_nub_clear_watchpoint
;
329 // B_DEBUG_MESSAGE_SET_SIGNAL_MASKS
332 thread_id thread
; // the thread
333 uint64 ignore_mask
; // the mask for signals the
334 // debugger wishes not to be
336 uint64 ignore_once_mask
; // the mask for signals the
337 // debugger wishes not to be
338 // notified of when they next
340 debug_signal_mask_op ignore_op
; // what to do with ignore_mask
341 debug_signal_mask_op ignore_once_op
; // what to do with
343 } debug_nub_set_signal_masks
;
345 // B_DEBUG_MESSAGE_GET_SIGNAL_MASKS
348 port_id reply_port
; // port to send the reply to
349 thread_id thread
; // the thread
350 } debug_nub_get_signal_masks
;
353 status_t error
; // B_OK, if the thread exists
354 uint64 ignore_mask
; // the mask for signals the debugger wishes
355 // not to be notified of
356 uint64 ignore_once_mask
; // the mask for signals the debugger wishes
357 // not to be notified of when they next
359 } debug_nub_get_signal_masks_reply
;
361 // B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER
364 int signal
; // the signal
365 struct sigaction handler
; // the new signal handler
366 } debug_nub_set_signal_handler
;
368 // B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER
371 port_id reply_port
; // port to send the reply to
372 int signal
; // the signal
373 } debug_nub_get_signal_handler
;
376 status_t error
; // B_OK, if the thread exists
377 struct sigaction handler
; // the signal handler
378 } debug_nub_get_signal_handler_reply
;
380 // B_DEBUG_MESSAGE_PREPARE_HANDOVER
382 // no parameters, no reply
384 // B_DEBUG_START_PROFILER
386 struct debug_profile_function
{
387 addr_t base
; // function base address
388 size_t size
; // function size
392 port_id reply_port
; // port to send the reply to
393 thread_id thread
; // thread to profile
394 bigtime_t interval
; // sample interval
395 area_id sample_area
; // area into which the sample will be
397 int32 stack_depth
; // number of return address per hit
398 bool variable_stack_depth
;
399 // variable number of samples per hit;
400 // cf. debug_profiler_update
401 } debug_nub_start_profiler
;
405 int32 image_event
; // number of the last image event
406 bigtime_t interval
; // actual sample interval (might
407 // differ from the requested one)
408 } debug_nub_start_profiler_reply
;
410 // B_DEBUG_STOP_PROFILER
413 port_id reply_port
; // port to send the reply to
414 thread_id thread
; // thread to profile
415 } debug_nub_stop_profiler
;
417 // B_DEBUG_WRITE_CORE_FILE
420 port_id reply_port
; // port to send the reply to
421 char path
[B_PATH_NAME_LENGTH
];
422 // path of the core file; must not exist
423 // yet; must be absolute
424 } debug_nub_write_core_file
;
427 status_t error
; // B_OK on success
428 } debug_nub_write_core_file_reply
;
431 // reply is debug_profiler_update
433 // union of all messages structures sent to the debug nub thread
435 debug_nub_read_memory read_memory
;
436 debug_nub_write_memory write_memory
;
437 debug_nub_set_team_flags set_team_flags
;
438 debug_nub_set_thread_flags set_thread_flags
;
439 debug_nub_continue_thread continue_thread
;
440 debug_nub_set_cpu_state set_cpu_state
;
441 debug_nub_get_cpu_state get_cpu_state
;
442 debug_nub_set_breakpoint set_breakpoint
;
443 debug_nub_clear_breakpoint clear_breakpoint
;
444 debug_nub_set_watchpoint set_watchpoint
;
445 debug_nub_clear_watchpoint clear_watchpoint
;
446 debug_nub_set_signal_masks set_signal_masks
;
447 debug_nub_get_signal_masks get_signal_masks
;
448 debug_nub_set_signal_handler set_signal_handler
;
449 debug_nub_get_signal_handler get_signal_handler
;
450 debug_nub_start_profiler start_profiler
;
451 debug_nub_stop_profiler stop_profiler
;
452 debug_nub_write_core_file write_core_file
;
453 } debug_nub_message_data
;
457 // #pragma mark ----- messages to the debugger -----
459 // first member of all debugger messages -- not a message by itself
461 thread_id thread
; // the thread being the event origin
462 team_id team
; // the thread's team
463 port_id nub_port
; // port to debug nub for this team (only set
464 // for synchronous messages)
467 // B_DEBUGGER_MESSAGE_THREAD_DEBUGGED
471 } debug_thread_debugged
;
473 // B_DEBUGGER_MESSAGE_DEBUGGER_CALL
477 void *message
; // address of the message passed to
479 } debug_debugger_call
;
481 // B_DEBUGGER_MESSAGE_BREAKPOINT_HIT
485 debug_cpu_state cpu_state
; // cpu state
486 } debug_breakpoint_hit
;
488 // B_DEBUGGER_MESSAGE_WATCHPOINT_HIT
492 debug_cpu_state cpu_state
; // cpu state
493 } debug_watchpoint_hit
;
495 // B_DEBUGGER_MESSAGE_SINGLE_STEP
499 debug_cpu_state cpu_state
; // cpu state
502 // B_DEBUGGER_MESSAGE_PRE_SYSCALL
506 uint32 syscall
; // the syscall number
507 uint8 args
[128]; // syscall arguments
510 // B_DEBUGGER_MESSAGE_POST_SYSCALL
514 bigtime_t start_time
; // time of syscall start
515 bigtime_t end_time
; // time of syscall completion
516 uint64 return_value
; // the syscall's return value
517 uint32 syscall
; // the syscall number
518 uint8 args
[128]; // syscall arguments
519 } debug_post_syscall
;
521 // B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED
525 int signal
; // the signal
526 struct sigaction handler
; // the signal handler
527 bool deadly
; // true, if handling the signal will kill
529 } debug_signal_received
;
531 // B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED
535 debug_exception_type exception
; // the exception
536 int signal
; // the signal that will be sent,
537 // when the thread continues
539 } debug_exception_occurred
;
541 // B_DEBUGGER_MESSAGE_TEAM_CREATED
545 team_id new_team
; // the newly created team
546 } debug_team_created
;
548 // B_DEBUGGER_MESSAGE_TEAM_DELETED
551 debug_origin origin
; // thread is < 0, team is the deleted team
552 // (asynchronous message)
553 } debug_team_deleted
;
555 // B_DEBUGGER_MESSAGE_TEAM_EXEC
559 int32 image_event
; // number of the image event
562 // B_DEBUGGER_MESSAGE_THREAD_CREATED
565 debug_origin origin
; // the thread that created the new thread
566 team_id new_thread
; // the newly created thread
567 } debug_thread_created
;
569 // B_DEBUGGER_MESSAGE_THREAD_DELETED
572 debug_origin origin
; // the deleted thread (asynchronous message)
573 } debug_thread_deleted
;
575 // B_DEBUGGER_MESSAGE_IMAGE_CREATED
579 image_info info
; // info for the image
580 int32 image_event
; // number of the image event
581 } debug_image_created
;
583 // B_DEBUGGER_MESSAGE_IMAGE_DELETED
587 image_info info
; // info for the image
588 int32 image_event
; // number of the image event
589 } debug_image_deleted
;
591 // B_DEBUGGER_MESSAGE_PROFILER_UPDATE
595 int32 image_event
; // number of the last image event; all
596 // samples were recorded after this
597 // event and before the next one
598 int32 stack_depth
; // number of return addresses per tick
599 int32 sample_count
; // number of samples in the buffer
600 int32 dropped_ticks
; // number of ticks that had been
601 // dropped, since the buffer was full
602 bool variable_stack_depth
;
603 // the number of samples per hit is
604 // variable, i.e. the format for the
605 // samples of a hit in the buffer is
606 // <n> <sample 1> ... <sample n>
608 // <sample 1> ... <sample stack_depth>
609 bool stopped
; // if true, the thread is no longer
611 } debug_profiler_update
;
613 // B_DEBUGGER_MESSAGE_HANDED_OVER
616 debug_origin origin
; // thread is < 0, team is the deleted team
617 // (asynchronous message)
618 team_id debugger
; // the new debugger
619 port_id debugger_port
; // the port the new debugger uses
620 thread_id causing_thread
; // the thread that caused entering the
621 // debugger in the first place, -1 if the
622 // debugger wasn't attached automatically
625 // union of all messages structures sent to the debugger
627 debug_thread_debugged thread_debugged
;
628 debug_debugger_call debugger_call
;
629 debug_breakpoint_hit breakpoint_hit
;
630 debug_watchpoint_hit watchpoint_hit
;
631 debug_single_step single_step
;
632 debug_pre_syscall pre_syscall
;
633 debug_post_syscall post_syscall
;
634 debug_signal_received signal_received
;
635 debug_exception_occurred exception_occurred
;
636 debug_team_created team_created
;
637 debug_team_deleted team_deleted
;
638 debug_team_exec team_exec
;
639 debug_thread_created thread_created
;
640 debug_thread_deleted thread_deleted
;
641 debug_image_created image_created
;
642 debug_image_deleted image_deleted
;
643 debug_profiler_update profiler_update
;
644 debug_handed_over handed_over
;
646 debug_origin origin
; // for convenience (no real message)
647 } debug_debugger_message_data
;
650 extern void get_debug_message_string(debug_debugger_message message
,
651 char *buffer
, int32 bufferSize
);
652 extern void get_debug_exception_string(debug_exception_type exception
,
653 char *buffer
, int32 bufferSize
);
660 #endif // _DEBUGGER_H