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