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