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