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