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.
7 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
12 #include <arch/debug.h>
17 #include <ByteOrder.h>
18 #include <TypeConstants.h>
22 #include <debug_heap.h>
28 #include <vm/vm_types.h>
29 #include <vm/VMAddressSpace.h>
30 #include <vm/VMArea.h>
34 stack_frame
* previous
;
35 addr_t return_address
;
38 #define NUM_PREVIOUS_LOCATIONS 32
41 static bool is_kernel_stack_address(Thread
* thread
, addr_t address
);
45 already_visited(addr_t
* visited
, int32
* _last
, int32
* _num
, addr_t bp
)
51 for (i
= 0; i
< num
; i
++) {
52 if (visited
[(NUM_PREVIOUS_LOCATIONS
+ last
- i
) % NUM_PREVIOUS_LOCATIONS
] == bp
)
56 *_last
= last
= (last
+ 1) % NUM_PREVIOUS_LOCATIONS
;
59 if (num
< NUM_PREVIOUS_LOCATIONS
)
66 /*! Safe to be called only from outside the debugger.
69 get_next_frame_no_debugger(addr_t bp
, addr_t
* _next
, addr_t
* _ip
,
70 bool onKernelStack
, Thread
* thread
)
72 // TODO: Do this more efficiently in assembly.
75 && is_kernel_stack_address(thread
, bp
+ sizeof(frame
) - 1))
76 memcpy(&frame
, (void*)bp
, sizeof(frame
));
77 else if (user_memcpy(&frame
, (void*)bp
, sizeof(frame
)) != B_OK
)
80 *_ip
= frame
.return_address
;
81 *_next
= (addr_t
)frame
.previous
;
87 /*! Safe to be called only from inside the debugger.
90 get_next_frame_debugger(addr_t bp
, addr_t
* _next
, addr_t
* _ip
)
93 if (debug_memcpy(B_CURRENT_TEAM
, &frame
, (void*)bp
, sizeof(frame
)) != B_OK
)
96 *_ip
= frame
.return_address
;
97 *_next
= (addr_t
)frame
.previous
;
104 lookup_symbol(Thread
* thread
, addr_t address
, addr_t
* _baseAddress
,
105 const char** _symbolName
, const char** _imageName
, bool* _exactMatch
)
107 status_t status
= B_ENTRY_NOT_FOUND
;
109 if (IS_KERNEL_ADDRESS(address
)) {
111 status
= elf_debug_lookup_symbol_address(address
, _baseAddress
,
112 _symbolName
, _imageName
, _exactMatch
);
113 } else if (thread
!= NULL
&& thread
->team
!= NULL
) {
114 // try a lookup using the userland runtime loader structures
115 status
= elf_debug_lookup_user_symbol_address(thread
->team
, address
,
116 _baseAddress
, _symbolName
, _imageName
, _exactMatch
);
118 if (status
!= B_OK
) {
119 // try to locate the image in the images loaded into user space
120 status
= image_debug_lookup_user_symbol_address(thread
->team
,
121 address
, _baseAddress
, _symbolName
, _imageName
, _exactMatch
);
133 set_debug_argument_variable(int32 index
, uint64 value
)
136 snprintf(name
, sizeof(name
), "_arg%ld", index
);
137 set_debug_variable(name
, value
);
141 template<typename Type
>
143 read_function_argument_value(void* argument
, bool& _valueKnown
)
146 if (debug_memcpy(B_CURRENT_TEAM
, &value
, argument
, sizeof(Type
)) == B_OK
) {
157 print_demangled_call(const char* image
, const char* symbol
, addr_t args
,
158 bool noObjectMethod
, bool addDebugVariables
)
160 static const size_t kBufferSize
= 256;
161 char* buffer
= (char*)debug_malloc(kBufferSize
);
166 const char* name
= debug_demangle_symbol(symbol
, buffer
, kBufferSize
,
173 uint32
* arg
= (uint32
*)args
;
176 isObjectMethod
= false;
177 if (isObjectMethod
) {
178 const char* lastName
= strrchr(name
, ':') - 1;
179 int namespaceLength
= lastName
- name
;
182 if (debug_memcpy(B_CURRENT_TEAM
, &argValue
, arg
, 4) == B_OK
) {
183 kprintf("<%s> %.*s<\33[32m%#" B_PRIx32
"\33[0m>%s", image
,
184 namespaceLength
, name
, argValue
, lastName
);
186 kprintf("<%s> %.*s<???>%s", image
, namespaceLength
, name
, lastName
);
188 if (addDebugVariables
)
189 set_debug_variable("_this", argValue
);
192 kprintf("<%s> %s", image
, name
);
199 while (debug_get_next_demangled_argument(&cookie
, symbol
, buffer
,
200 kBufferSize
, &type
, &length
) == B_OK
) {
204 // retrieve value and type identifier
207 bool valueKnown
= false;
211 value
= read_function_argument_value
<int64
>(arg
, valueKnown
);
213 kprintf("int64: \33[34m%Ld\33[0m", value
);
216 value
= read_function_argument_value
<int32
>(arg
, valueKnown
);
218 kprintf("int32: \33[34m%ld\33[0m", (int32
)value
);
221 value
= read_function_argument_value
<int16
>(arg
, valueKnown
);
223 kprintf("int16: \33[34m%d\33[0m", (int16
)value
);
226 value
= read_function_argument_value
<int8
>(arg
, valueKnown
);
228 kprintf("int8: \33[34m%d\33[0m", (int8
)value
);
231 value
= read_function_argument_value
<uint64
>(arg
, valueKnown
);
233 kprintf("uint64: \33[34m%#Lx\33[0m", value
);
234 if (value
< 0x100000)
235 kprintf(" (\33[34m%Lu\33[0m)", value
);
239 value
= read_function_argument_value
<uint32
>(arg
, valueKnown
);
241 kprintf("uint32: \33[34m%#lx\33[0m", (uint32
)value
);
242 if (value
< 0x100000)
243 kprintf(" (\33[34m%lu\33[0m)", (uint32
)value
);
247 value
= read_function_argument_value
<uint16
>(arg
, valueKnown
);
249 kprintf("uint16: \33[34m%#x\33[0m (\33[34m%u\33[0m)",
250 (uint16
)value
, (uint16
)value
);
254 value
= read_function_argument_value
<uint8
>(arg
, valueKnown
);
256 kprintf("uint8: \33[34m%#x\33[0m (\33[34m%u\33[0m)",
257 (uint8
)value
, (uint8
)value
);
261 value
= read_function_argument_value
<uint8
>(arg
, valueKnown
);
263 kprintf("\33[34m%s\33[0m", value
? "true" : "false");
267 kprintf("%s: ", buffer
);
270 value
= read_function_argument_value
<uint32
>(arg
,
274 && (type
== B_POINTER_TYPE
|| type
== B_REF_TYPE
))
277 kprintf("\33[34m%#lx\33[0m", (uint32
)value
);
284 value
= read_function_argument_value
<uint64
>(arg
,
290 kprintf("\33[34m%#Lx\33[0m", value
);
297 if (valueKnown
&& type
== B_STRING_TYPE
) {
299 kprintf(" \33[31m\"<NULL>\"\33[0m");
300 else if (debug_strlcpy(B_CURRENT_TEAM
, buffer
, (char*)(addr_t
)value
,
301 kBufferSize
) < B_OK
) {
302 kprintf(" \33[31m\"<???>\"\33[0m");
304 kprintf(" \33[36m\"%s\"\33[0m", buffer
);
307 if (addDebugVariables
)
308 set_debug_argument_variable(i
, value
);
309 arg
= (uint32
*)((uint8
*)arg
+ length
);
323 print_demangled_call(const char* image
, const char* symbol
, addr_t args
,
324 bool noObjectMethod
, bool addDebugVariables
)
326 // Since x86_64 uses registers rather than the stack for the first 6
327 // arguments we cannot use the same method as x86 to read the function
328 // arguments. Maybe we need DWARF support in the kernel debugger. For now
329 // just print out the function signature without the argument values.
331 static const size_t kBufferSize
= 256;
332 char* buffer
= (char*)debug_malloc(kBufferSize
);
337 const char* name
= debug_demangle_symbol(symbol
, buffer
, kBufferSize
,
344 kprintf("<%s> %s(", image
, name
);
349 while (debug_get_next_demangled_argument(&cookie
, symbol
, buffer
,
350 kBufferSize
, &type
, &length
) == B_OK
) {
355 kprintf("%s", buffer
);
371 print_stack_frame(Thread
* thread
, addr_t ip
, addr_t bp
, addr_t nextBp
,
372 int32 callIndex
, bool demangle
)
383 // MSB set = kernel space/user space switch
384 if (diff
& ~((addr_t
)-1 >> 1))
387 status
= lookup_symbol(thread
, ip
, &baseAddress
, &symbol
, &image
,
390 kprintf("%2" B_PRId32
" %0*lx (+%4ld) %0*lx ", callIndex
,
391 B_PRINTF_POINTER_WIDTH
, bp
, diff
, B_PRINTF_POINTER_WIDTH
, ip
);
393 if (status
== B_OK
) {
394 if (exactMatch
&& demangle
) {
395 status
= print_demangled_call(image
, symbol
,
396 nextBp
+ sizeof(stack_frame
), false, false);
399 if (!exactMatch
|| !demangle
|| status
!= B_OK
) {
400 if (symbol
!= NULL
) {
401 kprintf("<%s> %s%s", image
, symbol
,
402 exactMatch
? "" : " (nearest)");
404 kprintf("<%s@%p> <unknown>", image
, (void*)baseAddress
);
407 kprintf(" + %#04lx\n", ip
- baseAddress
);
410 if (thread
!= NULL
&& thread
->team
!= NULL
411 && thread
->team
->address_space
!= NULL
) {
412 area
= thread
->team
->address_space
->LookupArea(ip
);
415 kprintf("%" B_PRId32
":%s@%p + %#lx\n", area
->id
, area
->name
,
416 (void*)area
->Base(), ip
- area
->Base());
424 print_iframe(iframe
* frame
)
426 bool isUser
= IFRAME_IS_USER(frame
);
429 kprintf("%s iframe at %p (end = %p)\n", isUser
? "user" : "kernel", frame
,
432 kprintf(" rax %#-18lx rbx %#-18lx rcx %#lx\n", frame
->ax
,
433 frame
->bx
, frame
->cx
);
434 kprintf(" rdx %#-18lx rsi %#-18lx rdi %#lx\n", frame
->dx
,
435 frame
->si
, frame
->di
);
436 kprintf(" rbp %#-18lx r8 %#-18lx r9 %#lx\n", frame
->bp
,
437 frame
->r8
, frame
->r9
);
438 kprintf(" r10 %#-18lx r11 %#-18lx r12 %#lx\n", frame
->r10
,
439 frame
->r11
, frame
->r12
);
440 kprintf(" r13 %#-18lx r14 %#-18lx r15 %#lx\n", frame
->r13
,
441 frame
->r14
, frame
->r15
);
442 kprintf(" rip %#-18lx rsp %#-18lx rflags %#lx\n", frame
->ip
,
443 frame
->sp
, frame
->flags
);
445 kprintf("%s iframe at %p (end = %p)\n", isUser
? "user" : "kernel", frame
,
446 isUser
? (void*)(frame
+ 1) : (void*)&frame
->user_sp
);
448 kprintf(" eax %#-10lx ebx %#-10lx ecx %#-10lx edx %#lx\n",
449 frame
->ax
, frame
->bx
, frame
->cx
, frame
->dx
);
450 kprintf(" esi %#-10lx edi %#-10lx ebp %#-10lx esp %#lx\n",
451 frame
->si
, frame
->di
, frame
->bp
, frame
->sp
);
452 kprintf(" eip %#-10lx eflags %#-10lx", frame
->ip
, frame
->flags
);
455 kprintf("user esp %#lx", frame
->user_sp
);
460 kprintf(" vector: %#lx, error code: %#lx\n", frame
->vector
,
466 setup_for_thread(char* arg
, Thread
** _thread
, addr_t
* _bp
,
467 phys_addr_t
* _oldPageDirectory
)
469 Thread
* thread
= NULL
;
472 thread_id id
= strtoul(arg
, NULL
, 0);
473 thread
= Thread::GetDebug(id
);
474 if (thread
== NULL
) {
475 kprintf("could not find thread %" B_PRId32
"\n", id
);
479 if (id
!= thread_get_current_thread_id()) {
480 // switch to the page directory of the new thread to be
481 // able to follow the stack trace into userland
482 phys_addr_t newPageDirectory
= x86_next_page_directory(
483 thread_get_current_thread(), thread
);
485 if (newPageDirectory
!= 0) {
486 *_oldPageDirectory
= x86_read_cr3();
487 x86_write_cr3(newPageDirectory
);
490 if (thread
->state
== B_THREAD_RUNNING
) {
491 // The thread is currently running on another CPU.
492 if (thread
->cpu
== NULL
)
494 arch_debug_registers
* registers
= debug_get_debug_registers(
495 thread
->cpu
->cpu_num
);
496 if (registers
== NULL
)
498 *_bp
= registers
->bp
;
500 // Read frame pointer from the thread's stack.
501 *_bp
= thread
->arch_info
.GetFramePointer();
507 if (thread
== NULL
) {
508 // if we don't have a thread yet, we want the current one
509 // (ebp has been set by the caller for this case already)
510 thread
= thread_get_current_thread();
519 is_double_fault_stack_address(int32 cpu
, addr_t address
)
522 addr_t bottom
= (addr_t
)x86_get_double_fault_stack(cpu
, &size
);
523 return address
>= bottom
&& address
< bottom
+ size
;
528 is_kernel_stack_address(Thread
* thread
, addr_t address
)
530 // We don't have a thread pointer in the early boot process, but then we are
531 // on the kernel stack for sure.
533 return IS_KERNEL_ADDRESS(address
);
535 // Also in the early boot process we might have a thread structure, but it
536 // might not have its kernel stack attributes set yet.
537 if (thread
->kernel_stack_top
== 0)
538 return IS_KERNEL_ADDRESS(address
);
540 return (address
>= thread
->kernel_stack_base
541 && address
< thread
->kernel_stack_top
)
542 || (thread
->cpu
!= NULL
543 && is_double_fault_stack_address(thread
->cpu
->cpu_num
, address
));
548 is_iframe(Thread
* thread
, addr_t frame
)
550 if (!is_kernel_stack_address(thread
, frame
))
553 addr_t previousFrame
= *(addr_t
*)frame
;
554 return ((previousFrame
& ~(addr_t
)IFRAME_TYPE_MASK
) == 0
555 && previousFrame
!= 0);
560 find_previous_iframe(Thread
* thread
, addr_t frame
)
562 // iterate backwards through the stack frames, until we hit an iframe
563 while (is_kernel_stack_address(thread
, frame
)) {
564 if (is_iframe(thread
, frame
))
565 return (iframe
*)frame
;
567 frame
= *(addr_t
*)frame
;
575 get_previous_iframe(Thread
* thread
, iframe
* frame
)
580 return find_previous_iframe(thread
, frame
->bp
);
585 get_current_iframe(Thread
* thread
)
587 if (thread
== thread_get_current_thread())
588 return x86_get_current_iframe();
590 // NOTE: This doesn't work, if the thread is running (on another CPU).
591 return find_previous_iframe(thread
, thread
->arch_info
.GetFramePointer());
595 #define CHECK_DEBUG_VARIABLE(_name, _member, _settable) \
596 if (strcmp(variableName, _name) == 0) { \
597 settable = _settable; \
603 find_debug_variable(const char* variableName
, bool& settable
)
605 iframe
* frame
= get_current_iframe(debug_get_debugged_thread());
610 CHECK_DEBUG_VARIABLE("cs", frame
->cs
, false);
611 CHECK_DEBUG_VARIABLE("ss", frame
->ss
, false);
612 CHECK_DEBUG_VARIABLE("r15", frame
->r15
, true);
613 CHECK_DEBUG_VARIABLE("r14", frame
->r14
, true);
614 CHECK_DEBUG_VARIABLE("r13", frame
->r13
, true);
615 CHECK_DEBUG_VARIABLE("r12", frame
->r12
, true);
616 CHECK_DEBUG_VARIABLE("r11", frame
->r11
, true);
617 CHECK_DEBUG_VARIABLE("r10", frame
->r10
, true);
618 CHECK_DEBUG_VARIABLE("r9", frame
->r9
, true);
619 CHECK_DEBUG_VARIABLE("r8", frame
->r8
, true);
620 CHECK_DEBUG_VARIABLE("rbp", frame
->bp
, true);
621 CHECK_DEBUG_VARIABLE("rsi", frame
->si
, true);
622 CHECK_DEBUG_VARIABLE("rdi", frame
->di
, true);
623 CHECK_DEBUG_VARIABLE("rdx", frame
->dx
, true);
624 CHECK_DEBUG_VARIABLE("rcx", frame
->cx
, true);
625 CHECK_DEBUG_VARIABLE("rbx", frame
->bx
, true);
626 CHECK_DEBUG_VARIABLE("rax", frame
->ax
, true);
627 CHECK_DEBUG_VARIABLE("rip", frame
->ip
, true);
628 CHECK_DEBUG_VARIABLE("rflags", frame
->flags
, true);
629 CHECK_DEBUG_VARIABLE("rsp", frame
->sp
, true);
631 CHECK_DEBUG_VARIABLE("gs", frame
->gs
, false);
632 CHECK_DEBUG_VARIABLE("fs", frame
->fs
, false);
633 CHECK_DEBUG_VARIABLE("es", frame
->es
, false);
634 CHECK_DEBUG_VARIABLE("ds", frame
->ds
, false);
635 CHECK_DEBUG_VARIABLE("cs", frame
->cs
, false);
636 CHECK_DEBUG_VARIABLE("edi", frame
->di
, true);
637 CHECK_DEBUG_VARIABLE("esi", frame
->si
, true);
638 CHECK_DEBUG_VARIABLE("ebp", frame
->bp
, true);
639 CHECK_DEBUG_VARIABLE("esp", frame
->sp
, true);
640 CHECK_DEBUG_VARIABLE("ebx", frame
->bx
, true);
641 CHECK_DEBUG_VARIABLE("edx", frame
->dx
, true);
642 CHECK_DEBUG_VARIABLE("ecx", frame
->cx
, true);
643 CHECK_DEBUG_VARIABLE("eax", frame
->ax
, true);
644 CHECK_DEBUG_VARIABLE("orig_eax", frame
->orig_eax
, true);
645 CHECK_DEBUG_VARIABLE("orig_edx", frame
->orig_edx
, true);
646 CHECK_DEBUG_VARIABLE("eip", frame
->ip
, true);
647 CHECK_DEBUG_VARIABLE("eflags", frame
->flags
, true);
649 if (IFRAME_IS_USER(frame
)) {
650 CHECK_DEBUG_VARIABLE("user_esp", frame
->user_sp
, true);
651 CHECK_DEBUG_VARIABLE("user_ss", frame
->user_ss
, false);
660 stack_trace(int argc
, char** argv
)
662 static const char* usage
= "usage: %s [-d] [ <thread id> ]\n"
663 "Prints a stack trace for the current, respectively the specified\n"
665 " -d - Disables the demangling of the symbols.\n"
666 " <thread id> - The ID of the thread for which to print the stack\n"
668 bool demangle
= true;
669 int32 threadIndex
= 1;
670 if (argc
> 1 && !strcmp(argv
[1], "-d")) {
675 if (argc
> threadIndex
+ 1
676 || (argc
== 2 && strcmp(argv
[1], "--help") == 0)) {
677 kprintf(usage
, argv
[0]);
681 addr_t previousLocations
[NUM_PREVIOUS_LOCATIONS
];
682 Thread
* thread
= NULL
;
683 phys_addr_t oldPageDirectory
= 0;
684 addr_t bp
= x86_get_stack_frame();
685 int32 num
= 0, last
= 0;
687 if (!setup_for_thread(argc
== threadIndex
+ 1 ? argv
[threadIndex
] : NULL
,
688 &thread
, &bp
, &oldPageDirectory
))
691 DebuggedThreadSetter
threadSetter(thread
);
693 if (thread
!= NULL
) {
694 kprintf("stack trace for thread %" B_PRId32
" \"%s\"\n", thread
->id
,
697 kprintf(" kernel stack: %p to %p\n",
698 (void*)thread
->kernel_stack_base
,
699 (void*)(thread
->kernel_stack_top
));
700 if (thread
->user_stack_base
!= 0) {
701 kprintf(" user stack: %p to %p\n",
702 (void*)thread
->user_stack_base
,
703 (void*)(thread
->user_stack_base
+ thread
->user_stack_size
));
707 kprintf("%-*s %-*s <image>:function + offset\n",
708 B_PRINTF_POINTER_WIDTH
, "frame", B_PRINTF_POINTER_WIDTH
, "caller");
710 bool onKernelStack
= true;
712 for (int32 callIndex
= 0;; callIndex
++) {
713 onKernelStack
= onKernelStack
714 && is_kernel_stack_address(thread
, bp
);
716 if (onKernelStack
&& is_iframe(thread
, bp
)) {
717 iframe
* frame
= (iframe
*)bp
;
720 print_stack_frame(thread
, frame
->ip
, bp
, frame
->bp
, callIndex
,
727 if (get_next_frame_debugger(bp
, &nextBp
, &ip
) != B_OK
) {
728 kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH
, bp
);
732 if (ip
== 0 || bp
== 0)
735 print_stack_frame(thread
, ip
, bp
, nextBp
, callIndex
, demangle
);
739 if (already_visited(previousLocations
, &last
, &num
, bp
)) {
740 kprintf("circular stack frame: %p!\n", (void*)bp
);
747 if (oldPageDirectory
!= 0) {
748 // switch back to the previous page directory to no cause any troubles
749 x86_write_cr3(oldPageDirectory
);
758 print_call(Thread
*thread
, addr_t eip
, addr_t ebp
, addr_t nextEbp
,
761 const char *symbol
, *image
;
765 bool demangled
= false;
766 int32
*arg
= (int32
*)(nextEbp
+ 8);
768 status
= lookup_symbol(thread
, eip
, &baseAddress
, &symbol
, &image
,
771 kprintf("%08lx %08lx ", ebp
, eip
);
773 if (status
== B_OK
) {
774 if (symbol
!= NULL
) {
775 if (exactMatch
&& (argCount
== 0 || argCount
== -1)) {
776 status
= print_demangled_call(image
, symbol
, (addr_t
)arg
,
777 argCount
== -1, true);
782 kprintf("<%s>:%s%s", image
, symbol
,
783 exactMatch
? "" : " (nearest)");
786 kprintf("<%s@%p>:unknown + 0x%04lx", image
,
787 (void *)baseAddress
, eip
- baseAddress
);
791 if (thread
->team
->address_space
!= NULL
)
792 area
= thread
->team
->address_space
->LookupArea(eip
);
794 kprintf("%ld:%s@%p + %#lx", area
->id
, area
->name
,
795 (void *)area
->Base(), eip
- area
->Base());
802 for (int32 i
= 0; i
< argCount
; i
++) {
805 kprintf("%#lx", *arg
);
806 if (*arg
> -0x10000 && *arg
< 0x10000)
807 kprintf(" (%ld)", *arg
);
809 set_debug_argument_variable(i
+ 1, *(uint32
*)arg
);
817 set_debug_variable("_frame", nextEbp
);
822 show_call(int argc
, char **argv
)
824 static const char* usage
825 = "usage: %s [ <thread id> ] <call index> [ -<arg count> ]\n"
826 "Prints a function call with parameters of the current, respectively\n"
827 "the specified thread.\n"
828 " <thread id> - The ID of the thread for which to print the call.\n"
829 " <call index> - The index of the call in the stack trace.\n"
830 " <arg count> - The number of call arguments to print (use 'c' to\n"
831 " force the C++ demangler to use class methods,\n"
832 " use 'd' to disable demangling).\n";
833 if (argc
== 2 && strcmp(argv
[1], "--help") == 0) {
834 kprintf(usage
, argv
[0]);
838 Thread
*thread
= NULL
;
839 phys_addr_t oldPageDirectory
= 0;
840 addr_t ebp
= x86_get_stack_frame();
843 if (argc
>= 2 && argv
[argc
- 1][0] == '-') {
844 if (argv
[argc
- 1][1] == 'c')
846 else if (argv
[argc
- 1][1] == 'd')
849 argCount
= strtoul(argv
[argc
- 1] + 1, NULL
, 0);
851 if (argCount
< -2 || argCount
> 16) {
852 kprintf("Invalid argument count \"%ld\".\n", argCount
);
858 if (argc
< 2 || argc
> 3) {
859 kprintf(usage
, argv
[0]);
863 if (!setup_for_thread(argc
== 3 ? argv
[1] : NULL
, &thread
, &ebp
,
867 DebuggedThreadSetter
threadSetter(thread
);
869 int32 callIndex
= strtoul(argv
[argc
== 3 ? 2 : 1], NULL
, 0);
872 kprintf("thread %ld, %s\n", thread
->id
, thread
->name
);
874 bool onKernelStack
= true;
876 for (int32 index
= 0; index
<= callIndex
; index
++) {
877 onKernelStack
= onKernelStack
878 && is_kernel_stack_address(thread
, ebp
);
880 if (onKernelStack
&& is_iframe(thread
, ebp
)) {
881 struct iframe
*frame
= (struct iframe
*)ebp
;
883 if (index
== callIndex
)
884 print_call(thread
, frame
->ip
, ebp
, frame
->bp
, argCount
);
890 if (get_next_frame_debugger(ebp
, &nextEbp
, &eip
) != B_OK
) {
891 kprintf("%08lx -- read fault\n", ebp
);
895 if (eip
== 0 || ebp
== 0)
898 if (index
== callIndex
)
899 print_call(thread
, eip
, ebp
, nextEbp
, argCount
);
908 if (oldPageDirectory
!= 0) {
909 // switch back to the previous page directory to not cause any troubles
910 x86_write_cr3(oldPageDirectory
);
919 dump_iframes(int argc
, char** argv
)
921 static const char* usage
= "usage: %s [ <thread id> ]\n"
922 "Prints the iframe stack for the current, respectively the specified\n"
924 " <thread id> - The ID of the thread for which to print the iframe\n"
926 if (argc
== 2 && strcmp(argv
[1], "--help") == 0) {
927 kprintf(usage
, argv
[0]);
931 Thread
* thread
= NULL
;
934 thread
= thread_get_current_thread();
935 } else if (argc
== 2) {
936 thread_id id
= strtoul(argv
[1], NULL
, 0);
937 thread
= Thread::GetDebug(id
);
938 if (thread
== NULL
) {
939 kprintf("could not find thread %" B_PRId32
"\n", id
);
942 } else if (argc
> 2) {
943 kprintf(usage
, argv
[0]);
947 if (thread
!= NULL
) {
948 kprintf("iframes for thread %" B_PRId32
" \"%s\"\n", thread
->id
,
952 DebuggedThreadSetter
threadSetter(thread
);
954 iframe
* frame
= find_previous_iframe(thread
, x86_get_stack_frame());
955 while (frame
!= NULL
) {
957 frame
= get_previous_iframe(thread
, frame
);
965 is_calling(Thread
* thread
, addr_t ip
, const char* pattern
, addr_t start
,
969 return ip
>= start
&& ip
< end
;
971 if (!IS_KERNEL_ADDRESS(ip
))
975 if (lookup_symbol(thread
, ip
, NULL
, &symbol
, NULL
, NULL
) != B_OK
)
978 return strstr(symbol
, pattern
);
983 cmd_in_context(int argc
, char** argv
)
986 print_debugger_command_usage(argv
[0]);
991 const char* commandLine
= argv
[1];
992 char threadIDString
[16];
993 if (parse_next_debug_command_argument(&commandLine
, threadIDString
,
994 sizeof(threadIDString
)) != B_OK
) {
995 kprintf("Failed to parse thread ID.\n");
999 if (commandLine
== NULL
) {
1000 print_debugger_command_usage(argv
[0]);
1005 if (!evaluate_debug_expression(threadIDString
, &threadID
, false))
1009 Thread
* thread
= Thread::GetDebug(threadID
);
1010 if (thread
== NULL
) {
1011 kprintf("Could not find thread with ID \"%s\".\n", threadIDString
);
1015 // switch the page directory, if necessary
1016 phys_addr_t oldPageDirectory
= 0;
1017 if (thread
!= thread_get_current_thread()) {
1018 phys_addr_t newPageDirectory
= x86_next_page_directory(
1019 thread_get_current_thread(), thread
);
1021 if (newPageDirectory
!= 0) {
1022 oldPageDirectory
= x86_read_cr3();
1023 x86_write_cr3(newPageDirectory
);
1027 // execute the command
1029 DebuggedThreadSetter
threadSetter(thread
);
1030 evaluate_debug_command(commandLine
);
1033 // reset the page directory
1034 if (oldPageDirectory
)
1035 x86_write_cr3(oldPageDirectory
);
1045 arch_debug_save_registers(arch_debug_registers
* registers
)
1047 // get the caller's frame pointer
1048 stack_frame
* frame
= (stack_frame
*)x86_get_stack_frame();
1049 registers
->bp
= (addr_t
)frame
->previous
;
1054 arch_debug_stack_trace(void)
1056 stack_trace(0, NULL
);
1061 arch_debug_contains_call(Thread
* thread
, const char* symbol
, addr_t start
,
1064 DebuggedThreadSetter
threadSetter(thread
);
1067 if (thread
== thread_get_current_thread())
1068 bp
= x86_get_stack_frame();
1070 if (thread
->state
== B_THREAD_RUNNING
) {
1071 // The thread is currently running on another CPU.
1072 if (thread
->cpu
== NULL
)
1074 arch_debug_registers
* registers
= debug_get_debug_registers(
1075 thread
->cpu
->cpu_num
);
1076 if (registers
== NULL
)
1080 // thread not running
1081 bp
= thread
->arch_info
.GetFramePointer();
1086 if (!is_kernel_stack_address(thread
, bp
))
1089 if (is_iframe(thread
, bp
)) {
1090 iframe
* frame
= (iframe
*)bp
;
1092 if (is_calling(thread
, frame
->ip
, symbol
, start
, end
))
1099 if (get_next_frame_no_debugger(bp
, &nextBp
, &ip
, true,
1101 || ip
== 0 || bp
== 0)
1104 if (is_calling(thread
, ip
, symbol
, start
, end
))
1119 arch_debug_get_caller(void)
1121 stack_frame
* frame
= (stack_frame
*)x86_get_stack_frame();
1122 return (void*)frame
->previous
->return_address
;
1126 /*! Captures a stack trace (the return addresses) of the current thread.
1127 \param returnAddresses The array the return address shall be written to.
1128 \param maxCount The maximum number of return addresses to be captured.
1129 \param skipIframes The number of interrupt frames that shall be skipped. If
1130 greater than 0, \a skipFrames is ignored.
1131 \param skipFrames The number of stack frames that shall be skipped.
1132 \param flags A combination of one or two of the following:
1133 - \c STACK_TRACE_KERNEL: Capture kernel return addresses.
1134 - \c STACK_TRACE_USER: Capture user return addresses.
1135 \return The number of return addresses written to the given array.
1138 arch_debug_get_stack_trace(addr_t
* returnAddresses
, int32 maxCount
,
1139 int32 skipIframes
, int32 skipFrames
, uint32 flags
)
1141 // Keep skipping normal stack frames until we've skipped the iframes we're
1142 // supposed to skip.
1143 if (skipIframes
> 0)
1144 skipFrames
= INT_MAX
;
1146 Thread
* thread
= thread_get_current_thread();
1148 addr_t bp
= x86_get_stack_frame();
1149 bool onKernelStack
= true;
1151 while (bp
!= 0 && count
< maxCount
) {
1152 onKernelStack
= onKernelStack
1153 && is_kernel_stack_address(thread
, bp
);
1154 if (!onKernelStack
&& (flags
& STACK_TRACE_USER
) == 0)
1160 if (onKernelStack
&& is_iframe(thread
, bp
)) {
1161 iframe
* frame
= (iframe
*)bp
;
1165 if (skipIframes
> 0) {
1166 if (--skipIframes
== 0)
1170 if (get_next_frame_no_debugger(bp
, &nextBp
, &ip
,
1171 onKernelStack
, thread
) != B_OK
) {
1180 && ((flags
& STACK_TRACE_KERNEL
) != 0 || onKernelStack
)) {
1181 returnAddresses
[count
++] = ip
;
1192 /*! Returns the program counter of the currently debugged (respectively this)
1193 thread where the innermost interrupts happened. \a _isSyscall, if specified,
1194 is set to whether this interrupt frame was created by a syscall. Returns
1195 \c NULL, if there's no such frame or a problem occurred retrieving it;
1196 \a _isSyscall won't be set in this case.
1199 arch_debug_get_interrupt_pc(bool* _isSyscall
)
1201 iframe
* frame
= get_current_iframe(debug_get_debugged_thread());
1205 if (_isSyscall
!= NULL
)
1206 *_isSyscall
= frame
->type
== IFRAME_TYPE_SYSCALL
;
1208 return (void*)(addr_t
)frame
->ip
;
1212 /*! Sets the current thread to \c NULL.
1213 Invoked in the kernel debugger only.
1216 arch_debug_unset_current_thread(void)
1218 // Can't just write 0 to the GS base, that will cause the read from %gs:0
1219 // to fault. Instead point it at a NULL pointer, %gs:0 will get this value.
1220 static Thread
* unsetThread
= NULL
;
1222 x86_write_msr(IA32_MSR_GS_BASE
, (addr_t
)&unsetThread
);
1224 asm volatile("mov %0, %%gs:0" : : "r" (unsetThread
) : "memory");
1230 arch_is_debug_variable_defined(const char* variableName
)
1233 return find_debug_variable(variableName
, settable
);
1238 arch_set_debug_variable(const char* variableName
, uint64 value
)
1241 size_t* variable
= find_debug_variable(variableName
, settable
);
1242 if (variable
== NULL
)
1243 return B_ENTRY_NOT_FOUND
;
1246 return B_NOT_ALLOWED
;
1248 *variable
= (size_t)value
;
1254 arch_get_debug_variable(const char* variableName
, uint64
* value
)
1257 size_t* variable
= find_debug_variable(variableName
, settable
);
1258 if (variable
== NULL
)
1259 return B_ENTRY_NOT_FOUND
;
1266 struct gdb_register
{
1272 /*! Writes the contents of the CPU registers at some fixed outer stack frame or
1273 iframe into the given buffer in the format expected by gdb.
1275 This function is called in response to gdb's 'g' command.
1277 \param buffer The buffer to write the registers to.
1278 \param bufferSize The size of \a buffer in bytes.
1279 \return When successful, the number of bytes written to \a buffer, or a
1280 negative error code on error.
1283 arch_debug_gdb_get_registers(char* buffer
, size_t bufferSize
)
1285 iframe
* frame
= get_current_iframe(debug_get_debugged_thread());
1287 return B_NOT_SUPPORTED
;
1290 // For x86_64 the register order is:
1292 // rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
1293 // r8, r9, r10, r11, r12, r13, r14, r15,
1294 // rip, rflags, cs, ss, ds, es, fs, gs
1296 // Annoyingly, GDB wants all the registers as 64-bit values, but then
1297 // RFLAGS and the segment registers as 32-bit values, hence the need for
1298 // the type information.
1299 static const int32 kRegisterCount
= 24;
1300 gdb_register registers
[kRegisterCount
] = {
1301 { B_UINT64_TYPE
, frame
->ax
}, { B_UINT64_TYPE
, frame
->bx
},
1302 { B_UINT64_TYPE
, frame
->cx
}, { B_UINT64_TYPE
, frame
->dx
},
1303 { B_UINT64_TYPE
, frame
->si
}, { B_UINT64_TYPE
, frame
->di
},
1304 { B_UINT64_TYPE
, frame
->bp
}, { B_UINT64_TYPE
, frame
->sp
},
1305 { B_UINT64_TYPE
, frame
->r8
}, { B_UINT64_TYPE
, frame
->r9
},
1306 { B_UINT64_TYPE
, frame
->r10
}, { B_UINT64_TYPE
, frame
->r11
},
1307 { B_UINT64_TYPE
, frame
->r12
}, { B_UINT64_TYPE
, frame
->r13
},
1308 { B_UINT64_TYPE
, frame
->r14
}, { B_UINT64_TYPE
, frame
->r15
},
1309 { B_UINT64_TYPE
, frame
->ip
}, { B_UINT32_TYPE
, frame
->flags
},
1310 { B_UINT32_TYPE
, frame
->cs
}, { B_UINT32_TYPE
, frame
->ss
},
1311 { B_UINT32_TYPE
, 0 }, { B_UINT32_TYPE
, 0 },
1312 { B_UINT32_TYPE
, 0 }, { B_UINT32_TYPE
, 0 },
1315 // For x86 the register order is:
1317 // eax, ecx, edx, ebx,
1318 // esp, ebp, esi, edi,
1320 // cs, ss, ds, es, fs, gs
1322 // Note that even though the segment descriptors are actually 16 bits wide,
1323 // gdb requires them as 32 bit integers.
1324 static const int32 kRegisterCount
= 16;
1325 gdb_register registers
[kRegisterCount
] = {
1326 { B_UINT32_TYPE
, frame
->ax
}, { B_UINT32_TYPE
, frame
->cx
},
1327 { B_UINT32_TYPE
, frame
->dx
}, { B_UINT32_TYPE
, frame
->bx
},
1328 { B_UINT32_TYPE
, frame
->sp
}, { B_UINT32_TYPE
, frame
->bp
},
1329 { B_UINT32_TYPE
, frame
->si
}, { B_UINT32_TYPE
, frame
->di
},
1330 { B_UINT32_TYPE
, frame
->ip
}, { B_UINT32_TYPE
, frame
->flags
},
1331 { B_UINT32_TYPE
, frame
->cs
}, { B_UINT32_TYPE
, frame
->ds
},
1333 { B_UINT32_TYPE
, frame
->ds
}, { B_UINT32_TYPE
, frame
->es
},
1334 { B_UINT32_TYPE
, frame
->fs
}, { B_UINT32_TYPE
, frame
->gs
},
1338 const char* const bufferStart
= buffer
;
1340 for (int32 i
= 0; i
< kRegisterCount
; i
++) {
1341 // For some reason gdb wants the register dump in *big endian* format.
1343 switch (registers
[i
].type
) {
1345 result
= snprintf(buffer
, bufferSize
, "%016" B_PRIx64
,
1346 (uint64
)B_HOST_TO_BENDIAN_INT64(registers
[i
].value
));
1349 result
= snprintf(buffer
, bufferSize
, "%08" B_PRIx32
,
1350 (uint32
)B_HOST_TO_BENDIAN_INT32((uint32
)registers
[i
].value
));
1353 if (result
>= (int)bufferSize
)
1354 return B_BUFFER_OVERFLOW
;
1357 bufferSize
-= result
;
1360 return buffer
- bufferStart
;
1365 arch_debug_init(kernel_args
* args
)
1367 // at this stage, the debugger command system is alive
1369 add_debugger_command("where", &stack_trace
, "Same as \"sc\"");
1370 add_debugger_command("bt", &stack_trace
, "Same as \"sc\" (as in gdb)");
1371 add_debugger_command("sc", &stack_trace
,
1372 "Stack crawl for current thread (or any other)");
1373 add_debugger_command("iframe", &dump_iframes
,
1374 "Dump iframes for the specified thread");
1376 add_debugger_command("call", &show_call
, "Show call with arguments");
1378 add_debugger_command_etc("in_context", &cmd_in_context
,
1379 "Executes a command in the context of a given thread",
1380 "<thread ID> <command> ...\n"
1381 "Executes a command in the context of a given thread.\n",
1382 B_KDEBUG_DONT_PARSE_ARGUMENTS
);