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