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