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%d", 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%d\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%#x\33[0m", (uint32)value); 244 if (value < 0x100000) 245 kprintf(" (\33[34m%u\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%#x\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 %#-10x ebx %#-10x ecx %#-10x edx %#x\n", 451 frame->ax, frame->bx, frame->cx, frame->dx); 452 kprintf(" esi %#-10x edi %#-10x ebp %#-10x esp %#x\n", 453 frame->si, frame->di, frame->bp, frame->sp); 454 kprintf(" eip %#-10x eflags %#-10x", frame->ip, frame->flags); 455 if (isUser) { 456 // from user space 457 kprintf("user esp %#x", frame->user_sp); 458 } 459 kprintf("\n"); 460 #endif 461 462 kprintf(" vector: %#lx, error code: %#lx\n", 463 (long unsigned int)frame->vector, 464 (long unsigned int)frame->error_code); 465 } 466 467 468 static bool 469 setup_for_thread(char* arg, Thread** _thread, addr_t* _bp, 470 phys_addr_t* _oldPageDirectory) 471 { 472 Thread* thread = NULL; 473 474 if (arg != NULL) { 475 thread_id id = strtoul(arg, NULL, 0); 476 thread = Thread::GetDebug(id); 477 if (thread == NULL) { 478 kprintf("could not find thread %" B_PRId32 "\n", id); 479 return false; 480 } 481 482 if (id != thread_get_current_thread_id()) { 483 // switch to the page directory of the new thread to be 484 // able to follow the stack trace into userland 485 phys_addr_t newPageDirectory = x86_next_page_directory( 486 thread_get_current_thread(), thread); 487 488 if (newPageDirectory != 0) { 489 *_oldPageDirectory = x86_read_cr3(); 490 x86_write_cr3(newPageDirectory); 491 } 492 493 if (thread->state == B_THREAD_RUNNING) { 494 // The thread is currently running on another CPU. 495 if (thread->cpu == NULL) 496 return false; 497 arch_debug_registers* registers = debug_get_debug_registers( 498 thread->cpu->cpu_num); 499 if (registers == NULL) 500 return false; 501 *_bp = registers->bp; 502 } else { 503 // Read frame pointer from the thread's stack. 504 *_bp = thread->arch_info.GetFramePointer(); 505 } 506 } else 507 thread = NULL; 508 } 509 510 if (thread == NULL) { 511 // if we don't have a thread yet, we want the current one 512 // (ebp has been set by the caller for this case already) 513 thread = thread_get_current_thread(); 514 } 515 516 *_thread = thread; 517 return true; 518 } 519 520 521 static bool 522 is_double_fault_stack_address(int32 cpu, addr_t address) 523 { 524 size_t size; 525 addr_t bottom = (addr_t)x86_get_double_fault_stack(cpu, &size); 526 return address >= bottom && address < bottom + size; 527 } 528 529 530 static bool 531 is_kernel_stack_address(Thread* thread, addr_t address) 532 { 533 // We don't have a thread pointer in the early boot process, but then we are 534 // on the kernel stack for sure. 535 if (thread == NULL) 536 return IS_KERNEL_ADDRESS(address); 537 538 // Also in the early boot process we might have a thread structure, but it 539 // might not have its kernel stack attributes set yet. 540 if (thread->kernel_stack_top == 0) 541 return IS_KERNEL_ADDRESS(address); 542 543 return (address >= thread->kernel_stack_base 544 && address < thread->kernel_stack_top) 545 || (thread->cpu != NULL 546 && is_double_fault_stack_address(thread->cpu->cpu_num, address)); 547 } 548 549 550 static bool 551 is_iframe(Thread* thread, addr_t frame) 552 { 553 if (!is_kernel_stack_address(thread, frame)) 554 return false; 555 556 addr_t previousFrame = *(addr_t*)frame; 557 return ((previousFrame & ~(addr_t)IFRAME_TYPE_MASK) == 0 558 && previousFrame != 0); 559 } 560 561 562 static iframe* 563 find_previous_iframe(Thread* thread, addr_t frame) 564 { 565 // iterate backwards through the stack frames, until we hit an iframe 566 while (is_kernel_stack_address(thread, frame)) { 567 if (is_iframe(thread, frame)) 568 return (iframe*)frame; 569 570 frame = *(addr_t*)frame; 571 } 572 573 return NULL; 574 } 575 576 577 static iframe* 578 get_previous_iframe(Thread* thread, iframe* frame) 579 { 580 if (frame == NULL) 581 return NULL; 582 583 return find_previous_iframe(thread, frame->bp); 584 } 585 586 587 static iframe* 588 get_current_iframe(Thread* thread) 589 { 590 if (thread == thread_get_current_thread()) 591 return x86_get_current_iframe(); 592 593 // NOTE: This doesn't work, if the thread is running (on another CPU). 594 return find_previous_iframe(thread, thread->arch_info.GetFramePointer()); 595 } 596 597 598 #define CHECK_DEBUG_VARIABLE(_name, _member, _settable) \ 599 if (strcmp(variableName, _name) == 0) { \ 600 settable = _settable; \ 601 return (addr_t*)&_member; \ 602 } 603 604 605 static addr_t* 606 find_debug_variable(const char* variableName, bool& settable) 607 { 608 iframe* frame = get_current_iframe(debug_get_debugged_thread()); 609 if (frame == NULL) 610 return NULL; 611 612 #ifdef __x86_64__ 613 CHECK_DEBUG_VARIABLE("cs", frame->cs, false); 614 CHECK_DEBUG_VARIABLE("ss", frame->ss, false); 615 CHECK_DEBUG_VARIABLE("r15", frame->r15, true); 616 CHECK_DEBUG_VARIABLE("r14", frame->r14, true); 617 CHECK_DEBUG_VARIABLE("r13", frame->r13, true); 618 CHECK_DEBUG_VARIABLE("r12", frame->r12, true); 619 CHECK_DEBUG_VARIABLE("r11", frame->r11, true); 620 CHECK_DEBUG_VARIABLE("r10", frame->r10, true); 621 CHECK_DEBUG_VARIABLE("r9", frame->r9, true); 622 CHECK_DEBUG_VARIABLE("r8", frame->r8, true); 623 CHECK_DEBUG_VARIABLE("rbp", frame->bp, true); 624 CHECK_DEBUG_VARIABLE("rsi", frame->si, true); 625 CHECK_DEBUG_VARIABLE("rdi", frame->di, true); 626 CHECK_DEBUG_VARIABLE("rdx", frame->dx, true); 627 CHECK_DEBUG_VARIABLE("rcx", frame->cx, true); 628 CHECK_DEBUG_VARIABLE("rbx", frame->bx, true); 629 CHECK_DEBUG_VARIABLE("rax", frame->ax, true); 630 CHECK_DEBUG_VARIABLE("rip", frame->ip, true); 631 CHECK_DEBUG_VARIABLE("rflags", frame->flags, true); 632 CHECK_DEBUG_VARIABLE("rsp", frame->sp, true); 633 #else 634 CHECK_DEBUG_VARIABLE("gs", frame->gs, false); 635 CHECK_DEBUG_VARIABLE("fs", frame->fs, false); 636 CHECK_DEBUG_VARIABLE("es", frame->es, false); 637 CHECK_DEBUG_VARIABLE("ds", frame->ds, false); 638 CHECK_DEBUG_VARIABLE("cs", frame->cs, false); 639 CHECK_DEBUG_VARIABLE("edi", frame->di, true); 640 CHECK_DEBUG_VARIABLE("esi", frame->si, true); 641 CHECK_DEBUG_VARIABLE("ebp", frame->bp, true); 642 CHECK_DEBUG_VARIABLE("esp", frame->sp, true); 643 CHECK_DEBUG_VARIABLE("ebx", frame->bx, true); 644 CHECK_DEBUG_VARIABLE("edx", frame->dx, true); 645 CHECK_DEBUG_VARIABLE("ecx", frame->cx, true); 646 CHECK_DEBUG_VARIABLE("eax", frame->ax, true); 647 CHECK_DEBUG_VARIABLE("orig_eax", frame->orig_eax, true); 648 CHECK_DEBUG_VARIABLE("orig_edx", frame->orig_edx, true); 649 CHECK_DEBUG_VARIABLE("eip", frame->ip, true); 650 CHECK_DEBUG_VARIABLE("eflags", frame->flags, true); 651 652 if (IFRAME_IS_USER(frame)) { 653 CHECK_DEBUG_VARIABLE("user_esp", frame->user_sp, true); 654 CHECK_DEBUG_VARIABLE("user_ss", frame->user_ss, false); 655 } 656 #endif 657 658 return NULL; 659 } 660 661 662 static int 663 stack_trace(int argc, char** argv) 664 { 665 static const char* usage = "usage: %s [-d] [ <thread id> ]\n" 666 "Prints a stack trace for the current, respectively the specified\n" 667 "thread.\n" 668 " -d - Disables the demangling of the symbols.\n" 669 " <thread id> - The ID of the thread for which to print the stack\n" 670 " trace.\n"; 671 bool demangle = true; 672 int32 threadIndex = 1; 673 if (argc > 1 && !strcmp(argv[1], "-d")) { 674 demangle = false; 675 threadIndex++; 676 } 677 678 if (argc > threadIndex + 1 679 || (argc == 2 && strcmp(argv[1], "--help") == 0)) { 680 kprintf(usage, argv[0]); 681 return 0; 682 } 683 684 addr_t previousLocations[NUM_PREVIOUS_LOCATIONS]; 685 Thread* thread = NULL; 686 phys_addr_t oldPageDirectory = 0; 687 addr_t bp = x86_get_stack_frame(); 688 int32 num = 0, last = 0; 689 690 if (!setup_for_thread(argc == threadIndex + 1 ? argv[threadIndex] : NULL, 691 &thread, &bp, &oldPageDirectory)) 692 return 0; 693 694 DebuggedThreadSetter threadSetter(thread); 695 696 if (thread != NULL) { 697 kprintf("stack trace for thread %" B_PRId32 " \"%s\"\n", thread->id, 698 thread->name); 699 700 kprintf(" kernel stack: %p to %p\n", 701 (void*)thread->kernel_stack_base, 702 (void*)(thread->kernel_stack_top)); 703 if (thread->user_stack_base != 0) { 704 kprintf(" user stack: %p to %p\n", 705 (void*)thread->user_stack_base, 706 (void*)(thread->user_stack_base + thread->user_stack_size)); 707 } 708 } 709 710 kprintf("%-*s %-*s <image>:function + offset\n", 711 B_PRINTF_POINTER_WIDTH, "frame", B_PRINTF_POINTER_WIDTH, "caller"); 712 713 bool onKernelStack = true; 714 715 for (int32 callIndex = 0; ; callIndex++) { 716 onKernelStack = onKernelStack 717 && is_kernel_stack_address(thread, bp); 718 719 if (onKernelStack && is_iframe(thread, bp)) { 720 iframe* frame = (iframe*)bp; 721 722 print_iframe(frame); 723 print_stack_frame(thread, frame->ip, bp, frame->bp, callIndex, 724 demangle); 725 726 bp = frame->bp; 727 } else { 728 addr_t ip, nextBp; 729 730 if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) { 731 kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH, bp); 732 break; 733 } 734 735 if (ip == 0 || bp == 0) 736 break; 737 738 print_stack_frame(thread, ip, bp, nextBp, callIndex, demangle); 739 bp = nextBp; 740 } 741 742 if (already_visited(previousLocations, &last, &num, bp)) { 743 kprintf("circular stack frame: %p!\n", (void*)bp); 744 break; 745 } 746 if (bp == 0) 747 break; 748 } 749 750 if (oldPageDirectory != 0) { 751 // switch back to the previous page directory to no cause any troubles 752 x86_write_cr3(oldPageDirectory); 753 } 754 755 return 0; 756 } 757 758 759 #ifndef __x86_64__ 760 static void 761 print_call(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp, 762 int32 argCount) 763 { 764 const char *symbol, *image; 765 addr_t baseAddress; 766 bool exactMatch; 767 status_t status; 768 bool demangled = false; 769 int32 *arg = (int32 *)(nextEbp + 8); 770 771 status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image, 772 &exactMatch); 773 774 kprintf("%08lx %08lx ", ebp, eip); 775 776 if (status == B_OK) { 777 if (symbol != NULL) { 778 if (exactMatch && (argCount == 0 || argCount == -1)) { 779 status = print_demangled_call(image, symbol, (addr_t)arg, 780 argCount == -1, true); 781 if (status == B_OK) 782 demangled = true; 783 } 784 if (!demangled) { 785 kprintf("<%s>:%s%s", image, symbol, 786 exactMatch ? "" : " (nearest)"); 787 } 788 } else { 789 kprintf("<%s@%p>:unknown + 0x%04lx", image, 790 (void *)baseAddress, eip - baseAddress); 791 } 792 } else { 793 VMArea *area = NULL; 794 if (thread->team->address_space != NULL) 795 area = thread->team->address_space->LookupArea(eip); 796 if (area != NULL) { 797 kprintf("%d:%s@%p + %#lx", area->id, area->name, 798 (void *)area->Base(), eip - area->Base()); 799 } 800 } 801 802 if (!demangled) { 803 kprintf("("); 804 805 for (int32 i = 0; i < argCount; i++) { 806 if (i > 0) 807 kprintf(", "); 808 kprintf("%#x", *arg); 809 if (*arg > -0x10000 && *arg < 0x10000) 810 kprintf(" (%d)", *arg); 811 812 set_debug_argument_variable(i + 1, *(uint32 *)arg); 813 arg++; 814 } 815 816 kprintf(")\n"); 817 } else 818 kprintf("\n"); 819 820 set_debug_variable("_frame", nextEbp); 821 } 822 823 824 static int 825 show_call(int argc, char **argv) 826 { 827 static const char* usage 828 = "usage: %s [ <thread id> ] <call index> [ -<arg count> ]\n" 829 "Prints a function call with parameters of the current, respectively\n" 830 "the specified thread.\n" 831 " <thread id> - The ID of the thread for which to print the call.\n" 832 " <call index> - The index of the call in the stack trace.\n" 833 " <arg count> - The number of call arguments to print (use 'c' to\n" 834 " force the C++ demangler to use class methods,\n" 835 " use 'd' to disable demangling).\n"; 836 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 837 kprintf(usage, argv[0]); 838 return 0; 839 } 840 841 Thread *thread = NULL; 842 phys_addr_t oldPageDirectory = 0; 843 addr_t ebp = x86_get_stack_frame(); 844 int32 argCount = 0; 845 846 if (argc >= 2 && argv[argc - 1][0] == '-') { 847 if (argv[argc - 1][1] == 'c') 848 argCount = -1; 849 else if (argv[argc - 1][1] == 'd') 850 argCount = -2; 851 else 852 argCount = strtoul(argv[argc - 1] + 1, NULL, 0); 853 854 if (argCount < -2 || argCount > 16) { 855 kprintf("Invalid argument count \"%d\".\n", argCount); 856 return 0; 857 } 858 argc--; 859 } 860 861 if (argc < 2 || argc > 3) { 862 kprintf(usage, argv[0]); 863 return 0; 864 } 865 866 if (!setup_for_thread(argc == 3 ? argv[1] : NULL, &thread, &ebp, 867 &oldPageDirectory)) 868 return 0; 869 870 DebuggedThreadSetter threadSetter(thread); 871 872 int32 callIndex = strtoul(argv[argc == 3 ? 2 : 1], NULL, 0); 873 874 if (thread != NULL) 875 kprintf("thread %d, %s\n", thread->id, thread->name); 876 877 bool onKernelStack = true; 878 879 for (int32 index = 0; index <= callIndex; index++) { 880 onKernelStack = onKernelStack 881 && is_kernel_stack_address(thread, ebp); 882 883 if (onKernelStack && is_iframe(thread, ebp)) { 884 struct iframe *frame = (struct iframe *)ebp; 885 886 if (index == callIndex) 887 print_call(thread, frame->ip, ebp, frame->bp, argCount); 888 889 ebp = frame->bp; 890 } else { 891 addr_t eip, nextEbp; 892 893 if (get_next_frame_debugger(ebp, &nextEbp, &eip) != B_OK) { 894 kprintf("%08lx -- read fault\n", ebp); 895 break; 896 } 897 898 if (eip == 0 || ebp == 0) 899 break; 900 901 if (index == callIndex) 902 print_call(thread, eip, ebp, nextEbp, argCount); 903 904 ebp = nextEbp; 905 } 906 907 if (ebp == 0) 908 break; 909 } 910 911 if (oldPageDirectory != 0) { 912 // switch back to the previous page directory to not cause any troubles 913 x86_write_cr3(oldPageDirectory); 914 } 915 916 return 0; 917 } 918 #endif 919 920 921 static int 922 dump_iframes(int argc, char** argv) 923 { 924 static const char* usage = "usage: %s [ <thread id> ]\n" 925 "Prints the iframe stack for the current, respectively the specified\n" 926 "thread.\n" 927 " <thread id> - The ID of the thread for which to print the iframe\n" 928 " stack.\n"; 929 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 930 kprintf(usage, argv[0]); 931 return 0; 932 } 933 934 Thread* thread = NULL; 935 936 if (argc < 2) { 937 thread = thread_get_current_thread(); 938 } else if (argc == 2) { 939 thread_id id = strtoul(argv[1], NULL, 0); 940 thread = Thread::GetDebug(id); 941 if (thread == NULL) { 942 kprintf("could not find thread %" B_PRId32 "\n", id); 943 return 0; 944 } 945 } else if (argc > 2) { 946 kprintf(usage, argv[0]); 947 return 0; 948 } 949 950 if (thread != NULL) { 951 kprintf("iframes for thread %" B_PRId32 " \"%s\"\n", thread->id, 952 thread->name); 953 } 954 955 DebuggedThreadSetter threadSetter(thread); 956 957 iframe* frame = find_previous_iframe(thread, x86_get_stack_frame()); 958 while (frame != NULL) { 959 print_iframe(frame); 960 frame = get_previous_iframe(thread, frame); 961 } 962 963 return 0; 964 } 965 966 967 static bool 968 is_calling(Thread* thread, addr_t ip, const char* pattern, addr_t start, 969 addr_t end) 970 { 971 if (pattern == NULL) 972 return ip >= start && ip < end; 973 974 if (!IS_KERNEL_ADDRESS(ip)) 975 return false; 976 977 const char* symbol; 978 if (lookup_symbol(thread, ip, NULL, &symbol, NULL, NULL) != B_OK) 979 return false; 980 981 return strstr(symbol, pattern); 982 } 983 984 985 static int 986 cmd_in_context(int argc, char** argv) 987 { 988 if (argc != 2) { 989 print_debugger_command_usage(argv[0]); 990 return 0; 991 } 992 993 // get the thread ID 994 const char* commandLine = argv[1]; 995 char threadIDString[16]; 996 if (parse_next_debug_command_argument(&commandLine, threadIDString, 997 sizeof(threadIDString)) != B_OK) { 998 kprintf("Failed to parse thread ID.\n"); 999 return 0; 1000 } 1001 1002 if (commandLine == NULL) { 1003 print_debugger_command_usage(argv[0]); 1004 return 0; 1005 } 1006 1007 uint64 threadID; 1008 if (!evaluate_debug_expression(threadIDString, &threadID, false)) 1009 return 0; 1010 1011 // get the thread 1012 Thread* thread = Thread::GetDebug(threadID); 1013 if (thread == NULL) { 1014 kprintf("Could not find thread with ID \"%s\".\n", threadIDString); 1015 return 0; 1016 } 1017 1018 // switch the page directory, if necessary 1019 phys_addr_t oldPageDirectory = 0; 1020 if (thread != thread_get_current_thread()) { 1021 phys_addr_t newPageDirectory = x86_next_page_directory( 1022 thread_get_current_thread(), thread); 1023 1024 if (newPageDirectory != 0) { 1025 oldPageDirectory = x86_read_cr3(); 1026 x86_write_cr3(newPageDirectory); 1027 } 1028 } 1029 1030 // execute the command 1031 { 1032 DebuggedThreadSetter threadSetter(thread); 1033 evaluate_debug_command(commandLine); 1034 } 1035 1036 // reset the page directory 1037 if (oldPageDirectory) 1038 x86_write_cr3(oldPageDirectory); 1039 1040 return 0; 1041 } 1042 1043 1044 // #pragma mark - 1045 1046 1047 void 1048 arch_debug_save_registers(arch_debug_registers* registers) 1049 { 1050 // get the caller's frame pointer 1051 stack_frame* frame = (stack_frame*)x86_get_stack_frame(); 1052 registers->bp = (addr_t)frame->previous; 1053 } 1054 1055 1056 void 1057 arch_debug_stack_trace(void) 1058 { 1059 stack_trace(0, NULL); 1060 } 1061 1062 1063 bool 1064 arch_debug_contains_call(Thread* thread, const char* symbol, addr_t start, 1065 addr_t end) 1066 { 1067 DebuggedThreadSetter threadSetter(thread); 1068 1069 addr_t bp; 1070 if (thread == thread_get_current_thread()) 1071 bp = x86_get_stack_frame(); 1072 else { 1073 if (thread->state == B_THREAD_RUNNING) { 1074 // The thread is currently running on another CPU. 1075 if (thread->cpu == NULL) 1076 return false; 1077 arch_debug_registers* registers = debug_get_debug_registers( 1078 thread->cpu->cpu_num); 1079 if (registers == NULL) 1080 return false; 1081 bp = registers->bp; 1082 } else { 1083 // thread not running 1084 bp = thread->arch_info.GetFramePointer(); 1085 } 1086 } 1087 1088 for (;;) { 1089 if (!is_kernel_stack_address(thread, bp)) 1090 break; 1091 1092 if (is_iframe(thread, bp)) { 1093 iframe* frame = (iframe*)bp; 1094 1095 if (is_calling(thread, frame->ip, symbol, start, end)) 1096 return true; 1097 1098 bp = frame->bp; 1099 } else { 1100 addr_t ip, nextBp; 1101 1102 if (get_next_frame_no_debugger(bp, &nextBp, &ip, true, 1103 thread) != B_OK 1104 || ip == 0 || bp == 0) 1105 break; 1106 1107 if (is_calling(thread, ip, symbol, start, end)) 1108 return true; 1109 1110 bp = nextBp; 1111 } 1112 1113 if (bp == 0) 1114 break; 1115 } 1116 1117 return false; 1118 } 1119 1120 1121 /*! Captures a stack trace (the return addresses) of the current thread. 1122 \param returnAddresses The array the return address shall be written to. 1123 \param maxCount The maximum number of return addresses to be captured. 1124 \param skipIframes The number of interrupt frames that shall be skipped. If 1125 greater than 0, \a skipFrames is ignored. 1126 \param skipFrames The number of stack frames that shall be skipped. 1127 \param flags A combination of one or two of the following: 1128 - \c STACK_TRACE_KERNEL: Capture kernel return addresses. 1129 - \c STACK_TRACE_USER: Capture user return addresses. 1130 \return The number of return addresses written to the given array. 1131 */ 1132 int32 1133 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, 1134 int32 skipIframes, int32 skipFrames, uint32 flags) 1135 { 1136 // Keep skipping normal stack frames until we've skipped the iframes we're 1137 // supposed to skip. 1138 if (skipIframes > 0) 1139 skipFrames = INT_MAX; 1140 1141 Thread* thread = thread_get_current_thread(); 1142 int32 count = 0; 1143 addr_t bp = x86_get_stack_frame(); 1144 bool onKernelStack = true; 1145 1146 if ((flags & (STACK_TRACE_KERNEL | STACK_TRACE_USER)) == STACK_TRACE_USER) { 1147 iframe* frame = x86_get_user_iframe(); 1148 if (frame == NULL) 1149 return 0; 1150 1151 bp = (addr_t)frame; 1152 } 1153 1154 while (bp != 0 && count < maxCount) { 1155 onKernelStack = onKernelStack 1156 && is_kernel_stack_address(thread, bp); 1157 if (!onKernelStack && (flags & STACK_TRACE_USER) == 0) 1158 break; 1159 1160 addr_t ip; 1161 addr_t nextBp; 1162 1163 if (onKernelStack && is_iframe(thread, bp)) { 1164 iframe* frame = (iframe*)bp; 1165 ip = frame->ip; 1166 nextBp = frame->bp; 1167 1168 if (skipIframes > 0) { 1169 if (--skipIframes == 0) 1170 skipFrames = 0; 1171 } 1172 } else { 1173 if (get_next_frame_no_debugger(bp, &nextBp, &ip, 1174 onKernelStack, thread) != B_OK) { 1175 break; 1176 } 1177 } 1178 1179 if (ip == 0) 1180 break; 1181 1182 if (skipFrames > 0) 1183 skipFrames--; 1184 else 1185 returnAddresses[count++] = ip; 1186 1187 bp = nextBp; 1188 } 1189 1190 return count; 1191 } 1192 1193 1194 /*! Returns the program counter of the currently debugged (respectively this) 1195 thread where the innermost interrupts happened. \a _isSyscall, if specified, 1196 is set to whether this interrupt frame was created by a syscall. Returns 1197 \c NULL, if there's no such frame or a problem occurred retrieving it; 1198 \a _isSyscall won't be set in this case. 1199 */ 1200 void* 1201 arch_debug_get_interrupt_pc(bool* _isSyscall) 1202 { 1203 iframe* frame = get_current_iframe(debug_get_debugged_thread()); 1204 if (frame == NULL) 1205 return NULL; 1206 1207 if (_isSyscall != NULL) 1208 *_isSyscall = frame->type == IFRAME_TYPE_SYSCALL; 1209 1210 return (void*)(addr_t)frame->ip; 1211 } 1212 1213 1214 /*! Sets the current thread to \c NULL. 1215 Invoked in the kernel debugger only. 1216 */ 1217 void 1218 arch_debug_unset_current_thread(void) 1219 { 1220 // Can't just write 0 to the GS base, that will cause the read from %gs:0 1221 // to fault. Instead point it at a NULL pointer, %gs:0 will get this value. 1222 static Thread* unsetThread = NULL; 1223 #ifdef __x86_64__ 1224 x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&unsetThread); 1225 #else 1226 asm volatile("mov %0, %%gs:0" : : "r" (unsetThread) : "memory"); 1227 #endif 1228 } 1229 1230 1231 bool 1232 arch_is_debug_variable_defined(const char* variableName) 1233 { 1234 bool settable; 1235 return find_debug_variable(variableName, settable); 1236 } 1237 1238 1239 status_t 1240 arch_set_debug_variable(const char* variableName, uint64 value) 1241 { 1242 bool settable; 1243 size_t* variable = find_debug_variable(variableName, settable); 1244 if (variable == NULL) 1245 return B_ENTRY_NOT_FOUND; 1246 1247 if (!settable) 1248 return B_NOT_ALLOWED; 1249 1250 *variable = (size_t)value; 1251 return B_OK; 1252 } 1253 1254 1255 status_t 1256 arch_get_debug_variable(const char* variableName, uint64* value) 1257 { 1258 bool settable; 1259 size_t* variable = find_debug_variable(variableName, settable); 1260 if (variable == NULL) 1261 return B_ENTRY_NOT_FOUND; 1262 1263 *value = *variable; 1264 return B_OK; 1265 } 1266 1267 1268 struct gdb_register { 1269 int32 type; 1270 uint64 value; 1271 }; 1272 1273 1274 /*! Writes the contents of the CPU registers at some fixed outer stack frame or 1275 iframe into the given buffer in the format expected by gdb. 1276 1277 This function is called in response to gdb's 'g' command. 1278 1279 \param buffer The buffer to write the registers to. 1280 \param bufferSize The size of \a buffer in bytes. 1281 \return When successful, the number of bytes written to \a buffer, or a 1282 negative error code on error. 1283 */ 1284 ssize_t 1285 arch_debug_gdb_get_registers(char* buffer, size_t bufferSize) 1286 { 1287 iframe* frame = get_current_iframe(debug_get_debugged_thread()); 1288 if (frame == NULL) 1289 return B_NOT_SUPPORTED; 1290 1291 #ifdef __x86_64__ 1292 // For x86_64 the register order is: 1293 // 1294 // rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, 1295 // r8, r9, r10, r11, r12, r13, r14, r15, 1296 // rip, rflags, cs, ss, ds, es, fs, gs 1297 // 1298 // Annoyingly, GDB wants all the registers as 64-bit values, but then 1299 // RFLAGS and the segment registers as 32-bit values, hence the need for 1300 // the type information. 1301 static const int32 kRegisterCount = 24; 1302 gdb_register registers[kRegisterCount] = { 1303 { B_UINT64_TYPE, frame->ax }, { B_UINT64_TYPE, frame->bx }, 1304 { B_UINT64_TYPE, frame->cx }, { B_UINT64_TYPE, frame->dx }, 1305 { B_UINT64_TYPE, frame->si }, { B_UINT64_TYPE, frame->di }, 1306 { B_UINT64_TYPE, frame->bp }, { B_UINT64_TYPE, frame->sp }, 1307 { B_UINT64_TYPE, frame->r8 }, { B_UINT64_TYPE, frame->r9 }, 1308 { B_UINT64_TYPE, frame->r10 }, { B_UINT64_TYPE, frame->r11 }, 1309 { B_UINT64_TYPE, frame->r12 }, { B_UINT64_TYPE, frame->r13 }, 1310 { B_UINT64_TYPE, frame->r14 }, { B_UINT64_TYPE, frame->r15 }, 1311 { B_UINT64_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags }, 1312 { B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ss }, 1313 { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 }, 1314 { B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 }, 1315 }; 1316 #else 1317 // For x86 the register order is: 1318 // 1319 // eax, ecx, edx, ebx, 1320 // esp, ebp, esi, edi, 1321 // eip, eflags, 1322 // cs, ss, ds, es, fs, gs 1323 // 1324 // Note that even though the segment descriptors are actually 16 bits wide, 1325 // gdb requires them as 32 bit integers. 1326 static const int32 kRegisterCount = 16; 1327 gdb_register registers[kRegisterCount] = { 1328 { B_UINT32_TYPE, frame->ax }, { B_UINT32_TYPE, frame->cx }, 1329 { B_UINT32_TYPE, frame->dx }, { B_UINT32_TYPE, frame->bx }, 1330 { B_UINT32_TYPE, frame->sp }, { B_UINT32_TYPE, frame->bp }, 1331 { B_UINT32_TYPE, frame->si }, { B_UINT32_TYPE, frame->di }, 1332 { B_UINT32_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags }, 1333 { B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ds }, 1334 // assume ss == ds 1335 { B_UINT32_TYPE, frame->ds }, { B_UINT32_TYPE, frame->es }, 1336 { B_UINT32_TYPE, frame->fs }, { B_UINT32_TYPE, frame->gs }, 1337 }; 1338 #endif 1339 1340 const char* const bufferStart = buffer; 1341 1342 for (int32 i = 0; i < kRegisterCount; i++) { 1343 // For some reason gdb wants the register dump in *big endian* format. 1344 int result = 0; 1345 switch (registers[i].type) { 1346 case B_UINT64_TYPE: 1347 result = snprintf(buffer, bufferSize, "%016" B_PRIx64, 1348 (uint64)B_HOST_TO_BENDIAN_INT64(registers[i].value)); 1349 break; 1350 case B_UINT32_TYPE: 1351 result = snprintf(buffer, bufferSize, "%08" B_PRIx32, 1352 (uint32)B_HOST_TO_BENDIAN_INT32((uint32)registers[i].value)); 1353 break; 1354 } 1355 if (result >= (int)bufferSize) 1356 return B_BUFFER_OVERFLOW; 1357 1358 buffer += result; 1359 bufferSize -= result; 1360 } 1361 1362 return buffer - bufferStart; 1363 } 1364 1365 1366 status_t 1367 arch_debug_init(kernel_args* args) 1368 { 1369 // at this stage, the debugger command system is alive 1370 1371 add_debugger_command("where", &stack_trace, "Same as \"sc\""); 1372 add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)"); 1373 add_debugger_command("sc", &stack_trace, 1374 "Stack crawl for current thread (or any other)"); 1375 add_debugger_command("iframe", &dump_iframes, 1376 "Dump iframes for the specified thread"); 1377 #ifndef __x86_64__ 1378 add_debugger_command("call", &show_call, "Show call with arguments"); 1379 #endif 1380 add_debugger_command_etc("in_context", &cmd_in_context, 1381 "Executes a command in the context of a given thread", 1382 "<thread ID> <command> ...\n" 1383 "Executes a command in the context of a given thread.\n", 1384 B_KDEBUG_DONT_PARSE_ARGUMENTS); 1385 1386 return B_NO_ERROR; 1387 } 1388 1389