1 /* 2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11 #include <arch/debug.h> 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 16 #include <ByteOrder.h> 17 #include <TypeConstants.h> 18 19 #include <cpu.h> 20 #include <debug.h> 21 #include <debug_heap.h> 22 #include <elf.h> 23 #include <kernel.h> 24 #include <kimage.h> 25 #include <thread.h> 26 #include <vm/vm.h> 27 #include <vm/vm_types.h> 28 #include <vm/VMAddressSpace.h> 29 #include <vm/VMArea.h> 30 31 #include <arch_cpu.h> 32 33 34 struct stack_frame { 35 struct stack_frame *previous; 36 addr_t return_address; 37 }; 38 39 #define NUM_PREVIOUS_LOCATIONS 32 40 41 42 static bool 43 already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) 44 { 45 int32 last = *_last; 46 int32 num = *_num; 47 int32 i; 48 49 for (i = 0; i < num; i++) { 50 if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % NUM_PREVIOUS_LOCATIONS] == ebp) 51 return true; 52 } 53 54 *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS; 55 visited[last] = ebp; 56 57 if (num < NUM_PREVIOUS_LOCATIONS) 58 *_num = num + 1; 59 60 return false; 61 } 62 63 64 /*! Safe to be called only from outside the debugger. 65 */ 66 static status_t 67 get_next_frame_no_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) 68 { 69 // TODO: Do this more efficiently in assembly. 70 stack_frame frame; 71 if (user_memcpy(&frame, (void*)ebp, sizeof(frame)) != B_OK) 72 return B_BAD_ADDRESS; 73 74 *_eip = frame.return_address; 75 *_next = (addr_t)frame.previous; 76 77 return B_OK; 78 } 79 80 81 /*! Safe to be called only from inside the debugger. 82 */ 83 static status_t 84 get_next_frame_debugger(addr_t ebp, addr_t *_next, addr_t *_eip) 85 { 86 stack_frame frame; 87 if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)ebp, sizeof(frame)) != B_OK) 88 return B_BAD_ADDRESS; 89 90 *_eip = frame.return_address; 91 *_next = (addr_t)frame.previous; 92 93 return B_OK; 94 } 95 96 97 static status_t 98 lookup_symbol(Thread* thread, addr_t address, addr_t *_baseAddress, 99 const char **_symbolName, const char **_imageName, bool *_exactMatch) 100 { 101 status_t status = B_ENTRY_NOT_FOUND; 102 103 if (IS_KERNEL_ADDRESS(address)) { 104 // a kernel symbol 105 status = elf_debug_lookup_symbol_address(address, _baseAddress, 106 _symbolName, _imageName, _exactMatch); 107 } else if (thread != NULL && thread->team != NULL) { 108 // try a lookup using the userland runtime loader structures 109 status = elf_debug_lookup_user_symbol_address(thread->team, address, 110 _baseAddress, _symbolName, _imageName, _exactMatch); 111 112 if (status != B_OK) { 113 // try to locate the image in the images loaded into user space 114 status = image_debug_lookup_user_symbol_address(thread->team, 115 address, _baseAddress, _symbolName, _imageName, _exactMatch); 116 } 117 } 118 119 return status; 120 } 121 122 123 static void 124 set_debug_argument_variable(int32 index, uint64 value) 125 { 126 char name[8]; 127 snprintf(name, sizeof(name), "_arg%ld", index); 128 set_debug_variable(name, value); 129 } 130 131 132 template<typename Type> 133 static Type 134 read_function_argument_value(void* argument, bool& _valueKnown) 135 { 136 Type value; 137 if (debug_memcpy(B_CURRENT_TEAM, &value, argument, sizeof(Type)) == B_OK) { 138 _valueKnown = true; 139 return value; 140 } 141 142 _valueKnown = false; 143 return 0; 144 } 145 146 147 static status_t 148 print_demangled_call(const char* image, const char* symbol, addr_t args, 149 bool noObjectMethod, bool addDebugVariables) 150 { 151 static const size_t kBufferSize = 256; 152 char* buffer = (char*)debug_malloc(kBufferSize); 153 if (buffer == NULL) 154 return B_NO_MEMORY; 155 156 bool isObjectMethod; 157 const char* name = debug_demangle_symbol(symbol, buffer, kBufferSize, 158 &isObjectMethod); 159 if (name == NULL) { 160 debug_free(buffer); 161 return B_ERROR; 162 } 163 164 uint32* arg = (uint32*)args; 165 166 if (noObjectMethod) 167 isObjectMethod = false; 168 if (isObjectMethod) { 169 const char* lastName = strrchr(name, ':') - 1; 170 int namespaceLength = lastName - name; 171 172 uint32 argValue = 0; 173 if (debug_memcpy(B_CURRENT_TEAM, &argValue, arg, 4) == B_OK) { 174 kprintf("<%s> %.*s<\33[32m%#" B_PRIx32 "\33[0m>%s", image, 175 namespaceLength, name, argValue, lastName); 176 } else 177 kprintf("<%s> %.*s<???>%s", image, namespaceLength, name, lastName); 178 179 if (addDebugVariables) 180 set_debug_variable("_this", argValue); 181 arg++; 182 } else 183 kprintf("<%s> %s", image, name); 184 185 kprintf("("); 186 187 size_t length; 188 int32 type, i = 0; 189 uint32 cookie = 0; 190 while (debug_get_next_demangled_argument(&cookie, symbol, buffer, 191 kBufferSize, &type, &length) == B_OK) { 192 if (i++ > 0) 193 kprintf(", "); 194 195 // retrieve value and type identifier 196 197 uint64 value; 198 bool valueKnown = false; 199 200 switch (type) { 201 case B_INT64_TYPE: 202 value = read_function_argument_value<int64>(arg, valueKnown); 203 if (valueKnown) 204 kprintf("int64: \33[34m%Ld\33[0m", value); 205 break; 206 case B_INT32_TYPE: 207 value = read_function_argument_value<int32>(arg, valueKnown); 208 if (valueKnown) 209 kprintf("int32: \33[34m%ld\33[0m", (int32)value); 210 break; 211 case B_INT16_TYPE: 212 value = read_function_argument_value<int16>(arg, valueKnown); 213 if (valueKnown) 214 kprintf("int16: \33[34m%d\33[0m", (int16)value); 215 break; 216 case B_INT8_TYPE: 217 value = read_function_argument_value<int8>(arg, valueKnown); 218 if (valueKnown) 219 kprintf("int8: \33[34m%d\33[0m", (int8)value); 220 break; 221 case B_UINT64_TYPE: 222 value = read_function_argument_value<uint64>(arg, valueKnown); 223 if (valueKnown) { 224 kprintf("uint64: \33[34m%#Lx\33[0m", value); 225 if (value < 0x100000) 226 kprintf(" (\33[34m%Lu\33[0m)", value); 227 } 228 break; 229 case B_UINT32_TYPE: 230 value = read_function_argument_value<uint32>(arg, valueKnown); 231 if (valueKnown) { 232 kprintf("uint32: \33[34m%#lx\33[0m", (uint32)value); 233 if (value < 0x100000) 234 kprintf(" (\33[34m%lu\33[0m)", (uint32)value); 235 } 236 break; 237 case B_UINT16_TYPE: 238 value = read_function_argument_value<uint16>(arg, valueKnown); 239 if (valueKnown) { 240 kprintf("uint16: \33[34m%#x\33[0m (\33[34m%u\33[0m)", 241 (uint16)value, (uint16)value); 242 } 243 break; 244 case B_UINT8_TYPE: 245 value = read_function_argument_value<uint8>(arg, valueKnown); 246 if (valueKnown) { 247 kprintf("uint8: \33[34m%#x\33[0m (\33[34m%u\33[0m)", 248 (uint8)value, (uint8)value); 249 } 250 break; 251 case B_BOOL_TYPE: 252 value = read_function_argument_value<uint8>(arg, valueKnown); 253 if (valueKnown) 254 kprintf("\33[34m%s\33[0m", value ? "true" : "false"); 255 break; 256 default: 257 if (buffer[0]) 258 kprintf("%s: ", buffer); 259 260 if (length == 4) { 261 value = read_function_argument_value<uint32>(arg, 262 valueKnown); 263 if (valueKnown) { 264 if (value == 0 265 && (type == B_POINTER_TYPE || type == B_REF_TYPE)) 266 kprintf("NULL"); 267 else 268 kprintf("\33[34m%#lx\33[0m", (uint32)value); 269 } 270 break; 271 } 272 273 274 if (length == 8) { 275 value = read_function_argument_value<uint64>(arg, 276 valueKnown); 277 } else 278 value = (uint64)arg; 279 280 if (valueKnown) 281 kprintf("\33[34m%#Lx\33[0m", value); 282 break; 283 } 284 285 if (!valueKnown) 286 kprintf("???"); 287 288 if (valueKnown && type == B_STRING_TYPE) { 289 if (value == 0) 290 kprintf(" \33[31m\"<NULL>\"\33[0m"); 291 else if (debug_strlcpy(B_CURRENT_TEAM, buffer, (char*)(addr_t)value, 292 kBufferSize) < B_OK) { 293 kprintf(" \33[31m\"<???>\"\33[0m"); 294 } else 295 kprintf(" \33[36m\"%s\"\33[0m", buffer); 296 } 297 298 if (addDebugVariables) 299 set_debug_argument_variable(i, value); 300 arg = (uint32*)((uint8*)arg + length); 301 } 302 303 debug_free(buffer); 304 305 kprintf(")"); 306 return B_OK; 307 } 308 309 310 static void 311 print_stack_frame(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, 312 int32 callIndex, bool demangle) 313 { 314 const char *symbol, *image; 315 addr_t baseAddress; 316 bool exactMatch; 317 status_t status; 318 addr_t diff; 319 320 diff = nextEbp - ebp; 321 322 // kernel space/user space switch 323 if (diff & 0x80000000) 324 diff = 0; 325 326 status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image, 327 &exactMatch); 328 329 kprintf("%2ld %08lx (+%4ld) %08lx ", callIndex, ebp, diff, eip); 330 331 if (status == B_OK) { 332 if (exactMatch && demangle) { 333 status = print_demangled_call(image, symbol, nextEbp + 8, false, 334 false); 335 } 336 337 if (!exactMatch || !demangle || status != B_OK) { 338 if (symbol != NULL) { 339 kprintf("<%s>:%s%s", image, symbol, 340 exactMatch ? "" : " (nearest)"); 341 } else 342 kprintf("<%s@%p>:unknown", image, (void *)baseAddress); 343 } 344 345 kprintf(" + 0x%04lx\n", eip - baseAddress); 346 } else { 347 VMArea *area = NULL; 348 if (thread != NULL && thread->team != NULL 349 && thread->team->address_space != NULL) { 350 area = thread->team->address_space->LookupArea(eip); 351 } 352 if (area != NULL) { 353 kprintf("%ld:%s@%p + %#lx\n", area->id, area->name, 354 (void*)area->Base(), eip - area->Base()); 355 } else 356 kprintf("\n"); 357 } 358 } 359 360 361 static void 362 print_iframe(struct iframe *frame) 363 { 364 bool isUser = IFRAME_IS_USER(frame); 365 kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame, 366 isUser ? (uint32*)(frame + 1) : &frame->user_esp); 367 368 kprintf(" eax 0x%-9lx ebx 0x%-9lx ecx 0x%-9lx edx 0x%lx\n", 369 frame->eax, frame->ebx, frame->ecx, frame->edx); 370 kprintf(" esi 0x%-9lx edi 0x%-9lx ebp 0x%-9lx esp 0x%lx\n", 371 frame->esi, frame->edi, frame->ebp, frame->esp); 372 kprintf(" eip 0x%-9lx eflags 0x%-9lx", frame->eip, frame->flags); 373 if (isUser) { 374 // from user space 375 kprintf("user esp 0x%lx", frame->user_esp); 376 } 377 kprintf("\n"); 378 kprintf(" vector: 0x%lx, error code: 0x%lx\n", frame->vector, 379 frame->error_code); 380 } 381 382 383 static bool 384 setup_for_thread(char *arg, Thread **_thread, uint32 *_ebp, 385 uint32 *_oldPageDirectory) 386 { 387 Thread *thread = NULL; 388 389 if (arg != NULL) { 390 thread_id id = strtoul(arg, NULL, 0); 391 thread = Thread::GetDebug(id); 392 if (thread == NULL) { 393 kprintf("could not find thread %ld\n", id); 394 return false; 395 } 396 397 if (id != thread_get_current_thread_id()) { 398 // switch to the page directory of the new thread to be 399 // able to follow the stack trace into userland 400 uint32 newPageDirectory = x86_next_page_directory( 401 thread_get_current_thread(), thread); 402 403 if (newPageDirectory != 0) { 404 read_cr3(*_oldPageDirectory); 405 write_cr3(newPageDirectory); 406 } 407 408 if (thread->state == B_THREAD_RUNNING) { 409 // The thread is currently running on another CPU. 410 if (thread->cpu == NULL) 411 return false; 412 arch_debug_registers* registers = debug_get_debug_registers( 413 thread->cpu->cpu_num); 414 if (registers == NULL) 415 return false; 416 *_ebp = registers->ebp; 417 } else { 418 // read %ebp from the thread's stack stored by a pushad 419 *_ebp = thread->arch_info.current_stack.esp[2]; 420 } 421 } else 422 thread = NULL; 423 } 424 425 if (thread == NULL) { 426 // if we don't have a thread yet, we want the current one 427 // (ebp has been set by the caller for this case already) 428 thread = thread_get_current_thread(); 429 } 430 431 *_thread = thread; 432 return true; 433 } 434 435 436 static bool 437 is_double_fault_stack_address(int32 cpu, addr_t address) 438 { 439 size_t size; 440 addr_t bottom = (addr_t)x86_get_double_fault_stack(cpu, &size); 441 return address >= bottom && address < bottom + size; 442 } 443 444 445 static bool 446 is_kernel_stack_address(Thread* thread, addr_t address) 447 { 448 // We don't have a thread pointer in the early boot process, but then we are 449 // on the kernel stack for sure. 450 if (thread == NULL) 451 return IS_KERNEL_ADDRESS(address); 452 453 // Also in the early boot process we might have a thread structure, but it 454 // might not have its kernel stack attributes set yet. 455 if (thread->kernel_stack_top == 0) 456 return IS_KERNEL_ADDRESS(address); 457 458 return (address >= thread->kernel_stack_base 459 && address < thread->kernel_stack_top) 460 || (thread->cpu != NULL 461 && is_double_fault_stack_address(thread->cpu->cpu_num, address)); 462 } 463 464 465 static bool 466 is_iframe(Thread* thread, addr_t frame) 467 { 468 if (!is_kernel_stack_address(thread, frame)) 469 return false; 470 471 addr_t previousFrame = *(addr_t*)frame; 472 return ((previousFrame & ~IFRAME_TYPE_MASK) == 0 && previousFrame != 0); 473 } 474 475 476 static struct iframe * 477 find_previous_iframe(Thread *thread, addr_t frame) 478 { 479 // iterate backwards through the stack frames, until we hit an iframe 480 while (is_kernel_stack_address(thread, frame)) { 481 if (is_iframe(thread, frame)) 482 return (struct iframe*)frame; 483 484 frame = *(addr_t*)frame; 485 } 486 487 return NULL; 488 } 489 490 491 static struct iframe* 492 get_previous_iframe(Thread* thread, struct iframe* frame) 493 { 494 if (frame == NULL) 495 return NULL; 496 497 return find_previous_iframe(thread, frame->ebp); 498 } 499 500 501 static struct iframe* 502 get_current_iframe(Thread* thread) 503 { 504 if (thread == thread_get_current_thread()) 505 return i386_get_current_iframe(); 506 507 addr_t ebp = thread->arch_info.current_stack.esp[2]; 508 // NOTE: This doesn't work, if the thread is running (on another CPU). 509 return find_previous_iframe(thread, ebp); 510 } 511 512 513 uint32* 514 find_debug_variable(const char* variableName, bool& settable) 515 { 516 struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); 517 if (frame == NULL) 518 return NULL; 519 520 settable = false; 521 522 if (strcmp(variableName, "gs") == 0) { 523 return &frame->gs; 524 } else if (strcmp(variableName, "fs") == 0) { 525 return &frame->fs; 526 } else if (strcmp(variableName, "es") == 0) { 527 return &frame->es; 528 } else if (strcmp(variableName, "ds") == 0) { 529 return &frame->ds; 530 } else if (strcmp(variableName, "cs") == 0) { 531 return &frame->cs; 532 } else if (strcmp(variableName, "edi") == 0) { 533 settable = true; 534 return &frame->edi; 535 } else if (strcmp(variableName, "esi") == 0) { 536 settable = true; 537 return &frame->esi; 538 } else if (strcmp(variableName, "ebp") == 0) { 539 settable = true; 540 return &frame->ebp; 541 } else if (strcmp(variableName, "esp") == 0) { 542 settable = true; 543 return &frame->esp; 544 } else if (strcmp(variableName, "ebx") == 0) { 545 settable = true; 546 return &frame->ebx; 547 } else if (strcmp(variableName, "edx") == 0) { 548 settable = true; 549 return &frame->edx; 550 } else if (strcmp(variableName, "ecx") == 0) { 551 settable = true; 552 return &frame->ecx; 553 } else if (strcmp(variableName, "eax") == 0) { 554 settable = true; 555 return &frame->eax; 556 } else if (strcmp(variableName, "orig_eax") == 0) { 557 settable = true; 558 return &frame->orig_eax; 559 } else if (strcmp(variableName, "orig_edx") == 0) { 560 settable = true; 561 return &frame->orig_edx; 562 } else if (strcmp(variableName, "eip") == 0) { 563 settable = true; 564 return &frame->eip; 565 } else if (strcmp(variableName, "eflags") == 0) { 566 settable = true; 567 return &frame->flags; 568 } 569 570 if (IFRAME_IS_USER(frame)) { 571 if (strcmp(variableName, "user_esp") == 0) { 572 settable = true; 573 return &frame->user_esp; 574 } else if (strcmp(variableName, "user_ss") == 0) { 575 return &frame->user_ss; 576 } 577 } 578 579 return NULL; 580 } 581 582 583 static int 584 stack_trace(int argc, char **argv) 585 { 586 static const char* usage = "usage: %s [-d] [ <thread id> ]\n" 587 "Prints a stack trace for the current, respectively the specified\n" 588 "thread.\n" 589 " -d - Disables the demangling of the symbols.\n" 590 " <thread id> - The ID of the thread for which to print the stack\n" 591 " trace.\n"; 592 bool demangle = true; 593 int32 threadIndex = 1; 594 if (argc > 1 && !strcmp(argv[1], "-d")) { 595 demangle = false; 596 threadIndex++; 597 } 598 599 if (argc > threadIndex + 1 600 || (argc == 2 && strcmp(argv[1], "--help") == 0)) { 601 kprintf(usage, argv[0]); 602 return 0; 603 } 604 605 uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; 606 Thread *thread = NULL; 607 uint32 oldPageDirectory = 0; 608 uint32 ebp = x86_read_ebp(); 609 int32 num = 0, last = 0; 610 611 if (!setup_for_thread(argc == threadIndex + 1 ? argv[threadIndex] : NULL, 612 &thread, &ebp, &oldPageDirectory)) 613 return 0; 614 615 DebuggedThreadSetter threadSetter(thread); 616 617 if (thread != NULL) { 618 kprintf("stack trace for thread %ld \"%s\"\n", thread->id, 619 thread->name); 620 621 kprintf(" kernel stack: %p to %p\n", 622 (void *)thread->kernel_stack_base, 623 (void *)(thread->kernel_stack_top)); 624 if (thread->user_stack_base != 0) { 625 kprintf(" user stack: %p to %p\n", 626 (void *)thread->user_stack_base, 627 (void *)(thread->user_stack_base + thread->user_stack_size)); 628 } 629 } 630 631 kprintf("frame caller <image>:function + offset\n"); 632 633 bool onKernelStack = true; 634 635 for (int32 callIndex = 0;; callIndex++) { 636 onKernelStack = onKernelStack 637 && is_kernel_stack_address(thread, ebp); 638 639 if (onKernelStack && is_iframe(thread, ebp)) { 640 struct iframe *frame = (struct iframe *)ebp; 641 642 print_iframe(frame); 643 print_stack_frame(thread, frame->eip, ebp, frame->ebp, callIndex, 644 demangle); 645 646 ebp = frame->ebp; 647 } else { 648 addr_t eip, nextEbp; 649 650 if (get_next_frame_debugger(ebp, &nextEbp, &eip) != B_OK) { 651 kprintf("%08lx -- read fault\n", ebp); 652 break; 653 } 654 655 if (eip == 0 || ebp == 0) 656 break; 657 658 print_stack_frame(thread, eip, ebp, nextEbp, callIndex, demangle); 659 ebp = nextEbp; 660 } 661 662 if (already_visited(previousLocations, &last, &num, ebp)) { 663 kprintf("circular stack frame: %p!\n", (void *)ebp); 664 break; 665 } 666 if (ebp == 0) 667 break; 668 } 669 670 if (oldPageDirectory != 0) { 671 // switch back to the previous page directory to no cause any troubles 672 write_cr3(oldPageDirectory); 673 } 674 675 return 0; 676 } 677 678 679 static void 680 print_call(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, 681 int32 argCount) 682 { 683 const char *symbol, *image; 684 addr_t baseAddress; 685 bool exactMatch; 686 status_t status; 687 bool demangled = false; 688 int32 *arg = (int32 *)(nextEbp + 8); 689 690 status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image, 691 &exactMatch); 692 693 kprintf("%08lx %08lx ", ebp, eip); 694 695 if (status == B_OK) { 696 if (symbol != NULL) { 697 if (exactMatch && (argCount == 0 || argCount == -1)) { 698 status = print_demangled_call(image, symbol, (addr_t)arg, 699 argCount == -1, true); 700 if (status == B_OK) 701 demangled = true; 702 } 703 if (!demangled) { 704 kprintf("<%s>:%s%s", image, symbol, 705 exactMatch ? "" : " (nearest)"); 706 } 707 } else { 708 kprintf("<%s@%p>:unknown + 0x%04lx", image, 709 (void *)baseAddress, eip - baseAddress); 710 } 711 } else { 712 VMArea *area = NULL; 713 if (thread->team->address_space != NULL) 714 area = thread->team->address_space->LookupArea(eip); 715 if (area != NULL) { 716 kprintf("%ld:%s@%p + %#lx", area->id, area->name, 717 (void *)area->Base(), eip - area->Base()); 718 } 719 } 720 721 if (!demangled) { 722 kprintf("("); 723 724 for (int32 i = 0; i < argCount; i++) { 725 if (i > 0) 726 kprintf(", "); 727 kprintf("%#lx", *arg); 728 if (*arg > -0x10000 && *arg < 0x10000) 729 kprintf(" (%ld)", *arg); 730 731 set_debug_argument_variable(i + 1, *(uint32 *)arg); 732 arg++; 733 } 734 735 kprintf(")\n"); 736 } else 737 kprintf("\n"); 738 739 set_debug_variable("_frame", nextEbp); 740 } 741 742 743 static int 744 show_call(int argc, char **argv) 745 { 746 static const char* usage 747 = "usage: %s [ <thread id> ] <call index> [ -<arg count> ]\n" 748 "Prints a function call with parameters of the current, respectively\n" 749 "the specified thread.\n" 750 " <thread id> - The ID of the thread for which to print the call.\n" 751 " <call index> - The index of the call in the stack trace.\n" 752 " <arg count> - The number of call arguments to print (use 'c' to\n" 753 " force the C++ demangler to use class methods,\n" 754 " use 'd' to disable demangling).\n"; 755 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 756 kprintf(usage, argv[0]); 757 return 0; 758 } 759 760 Thread *thread = NULL; 761 uint32 oldPageDirectory = 0; 762 addr_t ebp = x86_read_ebp(); 763 int32 argCount = 0; 764 765 if (argc >= 2 && argv[argc - 1][0] == '-') { 766 if (argv[argc - 1][1] == 'c') 767 argCount = -1; 768 else if (argv[argc - 1][1] == 'd') 769 argCount = -2; 770 else 771 argCount = strtoul(argv[argc - 1] + 1, NULL, 0); 772 773 if (argCount < -2 || argCount > 16) { 774 kprintf("Invalid argument count \"%ld\".\n", argCount); 775 return 0; 776 } 777 argc--; 778 } 779 780 if (argc < 2 || argc > 3) { 781 kprintf(usage, argv[0]); 782 return 0; 783 } 784 785 if (!setup_for_thread(argc == 3 ? argv[1] : NULL, &thread, &ebp, 786 &oldPageDirectory)) 787 return 0; 788 789 DebuggedThreadSetter threadSetter(thread); 790 791 int32 callIndex = strtoul(argv[argc == 3 ? 2 : 1], NULL, 0); 792 793 if (thread != NULL) 794 kprintf("thread %ld, %s\n", thread->id, thread->name); 795 796 bool onKernelStack = true; 797 798 for (int32 index = 0; index <= callIndex; index++) { 799 onKernelStack = onKernelStack 800 && is_kernel_stack_address(thread, ebp); 801 802 if (onKernelStack && is_iframe(thread, ebp)) { 803 struct iframe *frame = (struct iframe *)ebp; 804 805 if (index == callIndex) 806 print_call(thread, frame->eip, ebp, frame->ebp, argCount); 807 808 ebp = frame->ebp; 809 } else { 810 addr_t eip, nextEbp; 811 812 if (get_next_frame_debugger(ebp, &nextEbp, &eip) != B_OK) { 813 kprintf("%08lx -- read fault\n", ebp); 814 break; 815 } 816 817 if (eip == 0 || ebp == 0) 818 break; 819 820 if (index == callIndex) 821 print_call(thread, eip, ebp, nextEbp, argCount); 822 823 ebp = nextEbp; 824 } 825 826 if (ebp == 0) 827 break; 828 } 829 830 if (oldPageDirectory != 0) { 831 // switch back to the previous page directory to not cause any troubles 832 write_cr3(oldPageDirectory); 833 } 834 835 return 0; 836 } 837 838 839 static int 840 dump_iframes(int argc, char **argv) 841 { 842 static const char* usage = "usage: %s [ <thread id> ]\n" 843 "Prints the iframe stack for the current, respectively the specified\n" 844 "thread.\n" 845 " <thread id> - The ID of the thread for which to print the iframe\n" 846 " stack.\n"; 847 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 848 kprintf(usage, argv[0]); 849 return 0; 850 } 851 852 Thread *thread = NULL; 853 854 if (argc < 2) { 855 thread = thread_get_current_thread(); 856 } else if (argc == 2) { 857 thread_id id = strtoul(argv[1], NULL, 0); 858 thread = Thread::GetDebug(id); 859 if (thread == NULL) { 860 kprintf("could not find thread %ld\n", id); 861 return 0; 862 } 863 } else if (argc > 2) { 864 kprintf(usage, argv[0]); 865 return 0; 866 } 867 868 if (thread != NULL) 869 kprintf("iframes for thread %ld \"%s\"\n", thread->id, thread->name); 870 871 DebuggedThreadSetter threadSetter(thread); 872 873 struct iframe* frame = find_previous_iframe(thread, x86_read_ebp()); 874 while (frame != NULL) { 875 print_iframe(frame); 876 frame = get_previous_iframe(thread, frame); 877 } 878 879 return 0; 880 } 881 882 883 static bool 884 is_calling(Thread *thread, addr_t eip, const char *pattern, 885 addr_t start, addr_t end) 886 { 887 if (pattern == NULL) 888 return eip >= start && eip < end; 889 890 if (!IS_KERNEL_ADDRESS(eip)) 891 return false; 892 893 const char *symbol; 894 if (lookup_symbol(thread, eip, NULL, &symbol, NULL, NULL) != B_OK) 895 return false; 896 897 return strstr(symbol, pattern); 898 } 899 900 901 static int 902 cmd_in_context(int argc, char** argv) 903 { 904 if (argc != 2) { 905 print_debugger_command_usage(argv[0]); 906 return 0; 907 } 908 909 // get the thread ID 910 const char* commandLine = argv[1]; 911 char threadIDString[16]; 912 if (parse_next_debug_command_argument(&commandLine, threadIDString, 913 sizeof(threadIDString)) != B_OK) { 914 kprintf("Failed to parse thread ID.\n"); 915 return 0; 916 } 917 918 if (commandLine == NULL) { 919 print_debugger_command_usage(argv[0]); 920 return 0; 921 } 922 923 uint64 threadID; 924 if (!evaluate_debug_expression(threadIDString, &threadID, false)) 925 return 0; 926 927 // get the thread 928 Thread* thread = Thread::GetDebug(threadID); 929 if (thread == NULL) { 930 kprintf("Could not find thread with ID \"%s\".\n", threadIDString); 931 return 0; 932 } 933 934 // switch the page directory, if necessary 935 uint32 oldPageDirectory = 0; 936 if (thread != thread_get_current_thread()) { 937 uint32 newPageDirectory = x86_next_page_directory( 938 thread_get_current_thread(), thread); 939 940 if (newPageDirectory != 0) { 941 read_cr3(oldPageDirectory); 942 write_cr3(newPageDirectory); 943 } 944 } 945 946 // execute the command 947 { 948 DebuggedThreadSetter threadSetter(thread); 949 evaluate_debug_command(commandLine); 950 } 951 952 // reset the page directory 953 if (oldPageDirectory) 954 write_cr3(oldPageDirectory); 955 956 return 0; 957 } 958 959 960 // #pragma mark - 961 962 963 void 964 arch_debug_save_registers(struct arch_debug_registers* registers) 965 { 966 // get the caller's frame pointer 967 stack_frame* frame = (stack_frame*)x86_read_ebp(); 968 registers->ebp = (addr_t)frame->previous; 969 } 970 971 972 void 973 arch_debug_stack_trace(void) 974 { 975 stack_trace(0, NULL); 976 } 977 978 979 bool 980 arch_debug_contains_call(Thread *thread, const char *symbol, 981 addr_t start, addr_t end) 982 { 983 DebuggedThreadSetter threadSetter(thread); 984 985 addr_t ebp; 986 if (thread == thread_get_current_thread()) 987 ebp = x86_read_ebp(); 988 else { 989 if (thread->state == B_THREAD_RUNNING) { 990 // The thread is currently running on another CPU. 991 if (thread->cpu == NULL) 992 return false; 993 arch_debug_registers* registers = debug_get_debug_registers( 994 thread->cpu->cpu_num); 995 if (registers == NULL) 996 return false; 997 ebp = registers->ebp; 998 } else { 999 // thread not running 1000 ebp = thread->arch_info.current_stack.esp[2]; 1001 } 1002 } 1003 1004 for (;;) { 1005 if (!is_kernel_stack_address(thread, ebp)) 1006 break; 1007 1008 if (is_iframe(thread, ebp)) { 1009 struct iframe *frame = (struct iframe *)ebp; 1010 1011 if (is_calling(thread, frame->eip, symbol, start, end)) 1012 return true; 1013 1014 ebp = frame->ebp; 1015 } else { 1016 addr_t eip, nextEbp; 1017 1018 if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != B_OK 1019 || eip == 0 || ebp == 0) 1020 break; 1021 1022 if (is_calling(thread, eip, symbol, start, end)) 1023 return true; 1024 1025 ebp = nextEbp; 1026 } 1027 1028 if (ebp == 0) 1029 break; 1030 } 1031 1032 return false; 1033 } 1034 1035 1036 void * 1037 arch_debug_get_caller(void) 1038 { 1039 struct stack_frame *frame = (struct stack_frame *)x86_read_ebp(); 1040 return (void *)frame->previous->return_address; 1041 } 1042 1043 1044 /*! Captures a stack trace (the return addresses) of the current thread. 1045 \param returnAddresses The array the return address shall be written to. 1046 \param maxCount The maximum number of return addresses to be captured. 1047 \param skipIframes The number of interrupt frames that shall be skipped. If 1048 greater than 0, \a skipFrames is ignored. 1049 \param skipFrames The number of stack frames that shall be skipped. 1050 \param flags A combination of one or two of the following: 1051 - \c STACK_TRACE_KERNEL: Capture kernel return addresses. 1052 - \c STACK_TRACE_USER: Capture user return addresses. 1053 \return The number of return addresses written to the given array. 1054 */ 1055 int32 1056 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, 1057 int32 skipIframes, int32 skipFrames, uint32 flags) 1058 { 1059 // Keep skipping normal stack frames until we've skipped the iframes we're 1060 // supposed to skip. 1061 if (skipIframes > 0) 1062 skipFrames = INT_MAX; 1063 1064 Thread* thread = thread_get_current_thread(); 1065 int32 count = 0; 1066 addr_t ebp = x86_read_ebp(); 1067 bool onKernelStack = true; 1068 1069 while (ebp != 0 && count < maxCount) { 1070 onKernelStack = onKernelStack 1071 && is_kernel_stack_address(thread, ebp); 1072 if (!onKernelStack && (flags & STACK_TRACE_USER) == 0) 1073 break; 1074 1075 addr_t eip; 1076 addr_t nextEbp; 1077 1078 if (onKernelStack && is_iframe(thread, ebp)) { 1079 struct iframe *frame = (struct iframe*)ebp; 1080 eip = frame->eip; 1081 nextEbp = frame->ebp; 1082 1083 if (skipIframes > 0) { 1084 if (--skipIframes == 0) 1085 skipFrames = 0; 1086 } 1087 } else { 1088 if (get_next_frame_no_debugger(ebp, &nextEbp, &eip) != B_OK) 1089 break; 1090 } 1091 1092 if (skipFrames <= 0 1093 && ((flags & STACK_TRACE_KERNEL) != 0 || onKernelStack)) { 1094 returnAddresses[count++] = eip; 1095 } else 1096 skipFrames--; 1097 1098 ebp = nextEbp; 1099 } 1100 1101 return count; 1102 } 1103 1104 1105 /*! Returns the program counter of the currently debugged (respectively this) 1106 thread where the innermost interrupts happened. \a _isSyscall, if specified, 1107 is set to whether this interrupt frame was created by a syscall. Returns 1108 \c NULL, if there's no such frame or a problem occurred retrieving it; 1109 \a _isSyscall won't be set in this case. 1110 */ 1111 void* 1112 arch_debug_get_interrupt_pc(bool* _isSyscall) 1113 { 1114 struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); 1115 if (frame == NULL) 1116 return NULL; 1117 1118 if (_isSyscall != NULL) 1119 *_isSyscall = frame->vector == 99; 1120 1121 return (void*)(addr_t)frame->eip; 1122 } 1123 1124 1125 /*! Sets the current thread to \c NULL. 1126 Invoked in the kernel debugger only. 1127 */ 1128 void 1129 arch_debug_unset_current_thread(void) 1130 { 1131 write_dr3(NULL); 1132 } 1133 1134 1135 bool 1136 arch_is_debug_variable_defined(const char* variableName) 1137 { 1138 bool settable; 1139 return find_debug_variable(variableName, settable); 1140 } 1141 1142 1143 status_t 1144 arch_set_debug_variable(const char* variableName, uint64 value) 1145 { 1146 bool settable; 1147 uint32* variable = find_debug_variable(variableName, settable); 1148 if (variable == NULL) 1149 return B_ENTRY_NOT_FOUND; 1150 1151 if (!settable) 1152 return B_NOT_ALLOWED; 1153 1154 *variable = (uint32)value; 1155 return B_OK; 1156 } 1157 1158 1159 status_t 1160 arch_get_debug_variable(const char* variableName, uint64* value) 1161 { 1162 bool settable; 1163 uint32* variable = find_debug_variable(variableName, settable); 1164 if (variable == NULL) 1165 return B_ENTRY_NOT_FOUND; 1166 1167 *value = *variable; 1168 return B_OK; 1169 } 1170 1171 1172 /*! Writes the contents of the CPU registers at some fixed outer stack frame or 1173 iframe into the given buffer in the format expected by gdb. 1174 1175 This function is called in response to gdb's 'g' command. 1176 1177 \param buffer The buffer to write the registers to. 1178 \param bufferSize The size of \a buffer in bytes. 1179 \return When successful, the number of bytes written to \a buffer, or a 1180 negative error code on error. 1181 */ 1182 ssize_t 1183 arch_debug_gdb_get_registers(char* buffer, size_t bufferSize) 1184 { 1185 struct iframe* frame = get_current_iframe(debug_get_debugged_thread()); 1186 if (frame == NULL) 1187 return B_NOT_SUPPORTED; 1188 1189 // For x86 the register order is: 1190 // 1191 // eax, ebx, ecx, edx, 1192 // esp, ebp, esi, edi, 1193 // eip, eflags, 1194 // cs, ss, ds, es 1195 // 1196 // Note that even though the segment descriptors are actually 16 bits wide, 1197 // gdb requires them as 32 bit integers. Note also that for some reason 1198 // gdb wants the register dump in *big endian* format. 1199 static const int32 kRegisterCount = 14; 1200 uint32 registers[kRegisterCount] = { 1201 frame->eax, frame->ebx, frame->ecx, frame->edx, 1202 frame->esp, frame->ebp, frame->esi, frame->edi, 1203 frame->eip, frame->flags, 1204 frame->cs, frame->ds, frame->ds, frame->es 1205 // assume ss == ds 1206 }; 1207 1208 const char* const bufferStart = buffer; 1209 1210 for (int32 i = 0; i < kRegisterCount; i++) { 1211 int result = snprintf(buffer, bufferSize, "%08" B_PRIx32, 1212 B_HOST_TO_BENDIAN_INT32(registers[i])); 1213 if (result >= (int)bufferSize) 1214 return B_BUFFER_OVERFLOW; 1215 1216 buffer += result; 1217 bufferSize -= result; 1218 } 1219 1220 return buffer - bufferStart; 1221 } 1222 1223 1224 status_t 1225 arch_debug_init(kernel_args *args) 1226 { 1227 // at this stage, the debugger command system is alive 1228 1229 add_debugger_command("where", &stack_trace, "Same as \"sc\""); 1230 add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)"); 1231 add_debugger_command("sc", &stack_trace, 1232 "Stack crawl for current thread (or any other)"); 1233 add_debugger_command("iframe", &dump_iframes, 1234 "Dump iframes for the specified thread"); 1235 add_debugger_command("call", &show_call, "Show call with arguments"); 1236 add_debugger_command_etc("in_context", &cmd_in_context, 1237 "Executes a command in the context of a given thread", 1238 "<thread ID> <command> ...\n" 1239 "Executes a command in the context of a given thread.\n", 1240 B_KDEBUG_DONT_PARSE_ARGUMENTS); 1241 1242 return B_NO_ERROR; 1243 } 1244 1245