• WinDbg常用命令系列---查看线程调用栈命令K*简介


    Windbg里的K*命令显示给定线程的堆栈帧以及相关信息,对于我们调试时,进行调用栈回溯有很大的帮助。

    一、K*命令使用方式

    在不同平台上,K*命令的使用组合如下

    User-Mode, x86 Processor

    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr [FrameCount]
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtrStackPtrInstructionPtr
    [~Thread] kd [WordCount]

    Kernel-Mode, x86 Processor

    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrFrameCount
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtrStackPtrInstructionPtr
    [Processor] kd [WordCount]
    

    User-Mode, x64 Processor

    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrFrameCount
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrInstructionPtrFrameCount
    [~Thread] kd [WordCount]
    

    Kernel-Mode, x64 Processor

    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrFrameCount
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrInstructionPtrFrameCount
    [Processor] kd [WordCount]
    

    User-Mode, ARM Processor

    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrFrameCount
    [~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrInstructionPtrFrameCount
    [~Thread] kd [WordCount]
    

    Kernel-Mode, ARM Processor

    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrFrameCount
    [Processor] k[b|p|P|v] [c] [n] [f] [L] [M] = StackPtrInstructionPtrFrameCount
    [Processor] kd [WordCount]

    二、参数说明

    • Thread
      指定要显示其堆栈的线程。如果省略此参数,将显示当前线程的堆栈。只能在用户模式下指定线程。
    • Processor
      指定要显示其堆栈的处理器。
    • b
      显示传递给堆栈跟踪中每个函数的前三个参数。
    • c
      显示干净的堆栈跟踪。每个显示行只包括模块名和函数名.
    • p
      显示在堆栈跟踪中调用的每个函数的所有参数。参数列表包括每个参数的数据类型、名称和值。p选项区分大小写。此参数需要完整的符号信息
    • P
      显示在堆栈跟踪中调用的每个函数的所有参数,如p参数。但是,对于P,功能参数打印在显示屏的第二行,而不是与其余数据打印在同一行上
    • v
      显示帧指针省略(FPO)信息。在基于x86的处理器上,显示还包括调用约定信息
    • n
      显示帧编号。
    • f
      显示相邻帧之间的距离。此距离是实际堆栈上分隔帧的字节数。
    • L
      隐藏显示中的源行。L区分大小写。
    • M
      使用调试器标记语言显示输出。显示器中的每个帧编号都是一个链接,您可以单击它来设置本地上下文并显示本地变量
    • FrameCount
      指定要显示的堆栈帧数。您应该以十六进制格式指定这个数字,除非您使用n(set number base)命令更改了基数。默认值为20(0x14),除非使用.kframes(设置堆栈长度)命令更改了默认值。
    • BasePtr

    指定堆栈跟踪的基指针。只有在命令后有等号(=)时,baseptr参数才可用

    • StackPtr
      指定堆栈跟踪的堆栈指针。如果省略stackptr和instructionptr,则该命令使用rsp(或esp)寄存器指定的堆栈指针和rip(或eip)寄存器指定的指令指针。
    • InstructionPtr
      指定堆栈跟踪的指令指针。如果省略stackptr和instructionptr,则该命令使用rsp(或esp)寄存器指定的堆栈指针和rip(或eip)寄存器指定的指令指针。
    • WordCount
      指定要转储的堆栈中的双字指针值的数目。默认值为20(0x14),除非使用.kframes(设置堆栈长度)命令更改默认值。

     三、使用环境

    Modes

    User mode, kernel mode

    Targets

    Live, crash dump

    Platforms

    All

     四、部分使用举例

     0:000> k
     # ChildEBP RetAddr  
    00 004ff308 00dd5e9a ConsoleApplication2!fun4 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01 004ff3f8 00dd5636 ConsoleApplication2!fun3+0x3a [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02 004ff4e4 00dd55b2 ConsoleApplication2!fun2+0x36 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03 004ff5cc 00dd400e ConsoleApplication2!fun1+0x32 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04 004ff6b0 00dd5bf3 ConsoleApplication2!fun0+0x2e [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05 004ff898 00dd6979 ConsoleApplication2!wmain+0x23 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06 004ff8e8 00dd6b6d ConsoleApplication2!__tmainCRTStartup+0x199 [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07 004ff8f0 76c38484 ConsoleApplication2!wmainCRTStartup+0xd [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08 004ff904 779441c8 KERNEL32!BaseThreadInitThunk+0x24
    09 004ff94c 77944198 ntdll!__RtlUserThreadStart+0x2f
    0a 004ff95c 00000000 ntdll!_RtlUserThreadStart+0x1b
    0:000> kb
     # ChildEBP RetAddr  Args to Child              
    00 004ff308 00dd5e9a 00000001 00000002 00000003 ConsoleApplication2!fun4 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01 004ff3f8 00dd5636 00000001 00000002 00000003 ConsoleApplication2!fun3+0x3a [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02 004ff4e4 00dd55b2 00000001 00000002 004ff6b0 ConsoleApplication2!fun2+0x36 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03 004ff5cc 00dd400e 00000001 004ff898 00dd1118 ConsoleApplication2!fun1+0x32 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04 004ff6b0 00dd5bf3 00dd1118 00dd1118 0028c000 ConsoleApplication2!fun0+0x2e [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05 004ff898 00dd6979 00000001 0050ac50 0050ad10 ConsoleApplication2!wmain+0x23 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06 004ff8e8 00dd6b6d 004ff904 76c38484 0028c000 ConsoleApplication2!__tmainCRTStartup+0x199 [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07 004ff8f0 76c38484 0028c000 76c38460 c36362f4 ConsoleApplication2!wmainCRTStartup+0xd [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08 004ff904 779441c8 0028c000 caf62646 00000000 KERNEL32!BaseThreadInitThunk+0x24
    09 004ff94c 77944198 ffffffff 7795f334 00000000 ntdll!__RtlUserThreadStart+0x2f
    0a 004ff95c 00000000 00dd1118 0028c000 00000000 ntdll!_RtlUserThreadStart+0x1b
    0:000> kp
     # ChildEBP RetAddr  
    00 004ff308 00dd5e9a ConsoleApplication2!fun4(int a = 0n1, int b = 0n2, int c = 0n3, int d = 0n4) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01 004ff3f8 00dd5636 ConsoleApplication2!fun3(int a = 0n1, int b = 0n2, int c = 0n3)+0x3a [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02 004ff4e4 00dd55b2 ConsoleApplication2!fun2(int a = 0n1, int b = 0n2)+0x36 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03 004ff5cc 00dd400e ConsoleApplication2!fun1(int a = 0n1)+0x32 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04 004ff6b0 00dd5bf3 ConsoleApplication2!fun0(void)+0x2e [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05 004ff898 00dd6979 ConsoleApplication2!wmain(int argc = 0n1, wchar_t ** argv = 0x0050ac50)+0x23 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06 004ff8e8 00dd6b6d ConsoleApplication2!__tmainCRTStartup(void)+0x199 [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07 004ff8f0 76c38484 ConsoleApplication2!wmainCRTStartup(void)+0xd [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08 004ff904 779441c8 KERNEL32!BaseThreadInitThunk+0x24
    09 004ff94c 77944198 ntdll!__RtlUserThreadStart+0x2f
    0a 004ff95c 00000000 ntdll!_RtlUserThreadStart+0x1b
    0:000> kP
     # ChildEBP RetAddr  
    00 004ff308 00dd5e9a ConsoleApplication2!fun4(
                int a = 0n1,
                int b = 0n2,
                int c = 0n3,
                int d = 0n4) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01 004ff3f8 00dd5636 ConsoleApplication2!fun3(
                int a = 0n1,
                int b = 0n2,
                int c = 0n3)+0x3a [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02 004ff4e4 00dd55b2 ConsoleApplication2!fun2(
                int a = 0n1,
                int b = 0n2)+0x36 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03 004ff5cc 00dd400e ConsoleApplication2!fun1(
                int a = 0n1)+0x32 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04 004ff6b0 00dd5bf3 ConsoleApplication2!fun0(void)+0x2e [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05 004ff898 00dd6979 ConsoleApplication2!wmain(
                int argc = 0n1,
                wchar_t ** argv = 0x0050ac50)+0x23 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06 004ff8e8 00dd6b6d ConsoleApplication2!__tmainCRTStartup(void)+0x199 [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07 004ff8f0 76c38484 ConsoleApplication2!wmainCRTStartup(void)+0xd [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08 004ff904 779441c8 KERNEL32!BaseThreadInitThunk+0x24
    09 004ff94c 77944198 ntdll!__RtlUserThreadStart+0x2f
    0a 004ff95c 00000000 ntdll!_RtlUserThreadStart+0x1b
    0:000> kv
     # ChildEBP RetAddr  Args to Child              
    00 004ff308 00dd5e9a 00000001 00000002 00000003 ConsoleApplication2!fun4 (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01 004ff3f8 00dd5636 00000001 00000002 00000003 ConsoleApplication2!fun3+0x3a (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02 004ff4e4 00dd55b2 00000001 00000002 004ff6b0 ConsoleApplication2!fun2+0x36 (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03 004ff5cc 00dd400e 00000001 004ff898 00dd1118 ConsoleApplication2!fun1+0x32 (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04 004ff6b0 00dd5bf3 00dd1118 00dd1118 0028c000 ConsoleApplication2!fun0+0x2e (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05 004ff898 00dd6979 00000001 0050ac50 0050ad10 ConsoleApplication2!wmain+0x23 (FPO: [Non-Fpo]) (CONV: cdecl) [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06 004ff8e8 00dd6b6d 004ff904 76c38484 0028c000 ConsoleApplication2!__tmainCRTStartup+0x199 (FPO: [Non-Fpo]) (CONV: cdecl) [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07 004ff8f0 76c38484 0028c000 76c38460 c36362f4 ConsoleApplication2!wmainCRTStartup+0xd (FPO: [Non-Fpo]) (CONV: cdecl) [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08 004ff904 779441c8 0028c000 caf62646 00000000 KERNEL32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo])
    09 004ff94c 77944198 ffffffff 7795f334 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
    0a 004ff95c 00000000 00dd1118 0028c000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
    0:000> k c
     #
    00 ConsoleApplication2!fun4
    01 ConsoleApplication2!fun3
    02 ConsoleApplication2!fun2
    03 ConsoleApplication2!fun1
    04 ConsoleApplication2!fun0
    05 ConsoleApplication2!wmain
    06 ConsoleApplication2!__tmainCRTStartup
    07 ConsoleApplication2!wmainCRTStartup
    08 KERNEL32!BaseThreadInitThunk
    09 ntdll!__RtlUserThreadStart
    0a ntdll!_RtlUserThreadStart
    0:000> k f
     #   Memory  ChildEBP RetAddr  
    00           004ff308 00dd5e9a ConsoleApplication2!fun4 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 74]
    01        f0 004ff3f8 00dd5636 ConsoleApplication2!fun3+0x3a [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 82]
    02        ec 004ff4e4 00dd55b2 ConsoleApplication2!fun2+0x36 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 89]
    03        e8 004ff5cc 00dd400e ConsoleApplication2!fun1+0x32 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 96]
    04        e4 004ff6b0 00dd5bf3 ConsoleApplication2!fun0+0x2e [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 103]
    05       1e8 004ff898 00dd6979 ConsoleApplication2!wmain+0x23 [e:sourceconsoleapplication1consoleapplication2consoleapplication2.cpp @ 111]
    06        50 004ff8e8 00dd6b6d ConsoleApplication2!__tmainCRTStartup+0x199 [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 623]
    07         8 004ff8f0 76c38484 ConsoleApplication2!wmainCRTStartup+0xd [f:ddvctoolscrtcrtw32dllstuffcrtexe.c @ 466]
    08        14 004ff904 779441c8 KERNEL32!BaseThreadInitThunk+0x24
    09        48 004ff94c 77944198 ntdll!__RtlUserThreadStart+0x2f
    0a        10 004ff95c 00000000 ntdll!_RtlUserThreadStart+0x1b
    0:000> kp L
     # ChildEBP RetAddr  
    00 004ff308 00dd5e9a ConsoleApplication2!fun4(int a = 0n1, int b = 0n2, int c = 0n3, int d = 0n4)
    01 004ff3f8 00dd5636 ConsoleApplication2!fun3(int a = 0n1, int b = 0n2, int c = 0n3)+0x3a
    02 004ff4e4 00dd55b2 ConsoleApplication2!fun2(int a = 0n1, int b = 0n2)+0x36
    03 004ff5cc 00dd400e ConsoleApplication2!fun1(int a = 0n1)+0x32
    04 004ff6b0 00dd5bf3 ConsoleApplication2!fun0(void)+0x2e
    05 004ff898 00dd6979 ConsoleApplication2!wmain(int argc = 0n1, wchar_t ** argv = 0x0050ac50)+0x23
    06 004ff8e8 00dd6b6d ConsoleApplication2!__tmainCRTStartup(void)+0x199
    07 004ff8f0 76c38484 ConsoleApplication2!wmainCRTStartup(void)+0xd
    08 004ff904 779441c8 KERNEL32!BaseThreadInitThunk+0x24
    09 004ff94c 77944198 ntdll!__RtlUserThreadStart+0x2f
    0a 004ff95c 00000000 ntdll!_RtlUserThreadStart+0x1b
    五、几点说明

    1. 发出k、kb、kp、kp或kv命令时,将以表格格式显示堆栈跟踪。如果启用了测线加载,则还会显示源模块和测线号。
    2. 堆栈跟踪包括堆栈帧的基指针、返回地址和函数名。
    3. 如果使用kp或kp命令,将显示在堆栈跟踪中调用的每个函数的完整参数。参数列表包括每个参数的数据类型、名称和值。
    4.  这个命令可能很慢。例如,当MyFunction1调用MyFunction2时,调试器必须具有MyFunction1的完整符号信息,才能显示此调用中传递的参数。此命令不能完全显示未在公共符号中公开的内部Microsoft Windows例程。
    5. 如果使用kb或kv命令,将显示传递给每个函数的前三个参数。如果使用kv命令,还会显示fpo数据,在基于x86的处理器上,kv命令还显示调用约定信息,当使用kv命令时,fpo信息将按以下格式添加到行的末尾。
      FPO textMeaning
      FPO: [non-Fpo]

      No FPO data for the frame.

      FPO: [N1,N2,N3]

      N1 is the total number of parameters.

      N2 is the number of DWORD values for the local variables.

      N3 is the number of registers that are saved.

      FPO: [N1,N2] TrapFrame @ Address

      N1 is the total number of parameters.

      N2 is the number of DWORD values for the locals.

      Address is the address of the trap frame.

      FPO: TaskGate Segment:0

      Segment is the segment selector for the task gate.

      FPO: [EBP 0xBase]

      Base is the base pointer for the frame.


    6. kd命令显示原始堆栈数据。每个双字值显示在单独的行上。将显示这些行的符号信息以及相关符号。此格式创建的列表比其他k*命令更详细。kd命令相当于使用堆栈地址作为参数的dds(显示内存)命令
    7. 如果在函数开头使用k命令(在函数prolog执行之前),则会收到不正确的结果。调试器使用帧寄存器来计算当前的回溯,在函数的prolog被执行之前,这个寄存器没有正确设置
    8. 在用户模式下,堆栈跟踪基于当前线程的堆栈。在内核模式下,堆栈跟踪基于当前寄存器上下文。可以设置寄存器上下文以匹配特定线程、上下文记录或陷阱帧
    
    
  • 相关阅读:
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(9)各种常用辅助类
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(7)声音播放、硬件信息、键盘模拟及钩子、鼠标模拟及钩子等设备相关
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(6)全屏截图、图标获取、图片打印、页面预览截屏、图片复杂操作等
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(4)CSV、Excel、INI文件、独立存储等文件相关
    DevExpress控件使用经验总结
    Winform开发框架之通用自动更新模块
    详解在数据查看界面中增加记录导航功能,你应该需要的
    使用Aspose.Cell控件实现多个Excel文件的合并
    厚积薄发,丰富的公用类库积累,助你高效进行系统开发(8)非对称加密、BASE64加密、MD5等常用加密处理
    WCF开发框架形成之旅如何实现X509证书加密
  • 原文地址:https://www.cnblogs.com/yilang/p/11357175.html
Copyright © 2020-2023  润新知