Windbg Stack Backtracing 명령어
thread별로 로컬 변수나 함수 호출간에 전달할 파라미터 정보를 저장하기 위한 임시 공간으로서 thread stack을 사용할 수 있는데, thread의 특정 시점에 사용 중이던 stack 정보를 역으로 추적해서 현재 실행 중인 함수의 위치까지 실행된 과정을 call stack으로 보여주고, 각 함수에 전달된 파라미터 정보를 확인하는 과정을 Stack backtracing이라고 합니다. 다음에 기회가 되면 이와 관련된 함수 호출 규약(function calling convention)과 stack 사용 및 해제하는 과정을 다루도록 하겠습니다.
어느 debugger를 이용하든지 thread의 stack을 backtracing 을 해서 stack frame 정보를 확인하는 것이 live debugging이나 post mortem debugging에 필수 과정이라고 할 수 있습니다. 특히 windbg의 경우 stack backtracing을 위해 k 명령어를 제공하고 있는데 파라미터에 따라서 그 사용법이 매우 다양하기 때문에 어떤 것을 사용해야 되는지 헷갈리는 경우가 많습니다. 제 경우에도 주로 사용하는 몇 개의 명령어만 쓰고 있는데 이번 기회에 세부 사용법을 정리해보도록 하겠습니다. 일단 이것 저것 많이 써보면서 몸으로 익히는 게 중요할 것 같습니다.
세부 내용은 WinDbg의 매뉴얼을 참고 했습니다.
구문
*유저모드에서
[ ~ Thread] k[b|p|P|v] [n] [f] [L] [FrameCount]
[ ~ Thread] k[b|p|P|v] [n] [f] [L] = BasePtr [FrameCount]
[ ~ Thread] k[b|p|P|v] [n] [f] [L] = BasePtr StackPtr InstructionPtr
[ ~ Thread] kd [WordCount]
*커널모드에서
[Processor] k[b|p|P|v] [n] [f] [L] [FrameCount]
[Processor] k[b|p|P|v] [n] [f] [L] = BasePtr [FrameCount]
[Processor] k[b|p|P|v] [n] [f] [L] = BasePtr StackPtr InstructionPtr
[Processor] kd [WordCount]
파라미터
b: 각 함수에 전달된 파라미터를 3개씩 보기
p: 함수에 전달된 모든 파라미터 보기
P: 함수에 전달된 모든 파라미터 보기. 줄바꿈을 이용해서 보여준다.
v: FPO(Frame Pointer Omission) 정보 보기
n: frame number 보기
f: frame 사이의 간격(실제 스택상에서 해당 frame의 bytes 수) 보기
L: 소스 상에서의 라인 번호 숨기기
실제 예
동일한 thread에서 k 명령어의 사용에 따른 차이점을 아래 예를 통해서 확인할 수 있습니다.
1: kd> k
ChildEBP RetAddr
83093868 8208fbf4 nt!MmAccessFault+0x106 [d:\vista_ldr\base\ntos\mm\mmfault.c @ 251]
83093868 82091f60 nt!_KiTrap0E+0xdc [d:\vista_ldr\base\ntos\ke\i386\trap.asm @ 5651]
830938f0 8fc9dbbb nt!Exfi386InterlockedExchangeUlong [d:\vista_ldr\base\ntos\ex\i386\intrlfst.asm @ 782]
83093904 8204b2e7 C7xUSBV3!powerWaitWakeCallback+0x1b [c:\projects\wibro\usb\xp\miniport.08.06.24_328\power.c @ 399]
8309392c 822cec69 nt!PopRequestCompletion+0x38 [d:\vista_ldr\base\ntos\po\pocall.c @ 349]
83093964 820acc1b nt!IovpLocalCompletionRoutine+0xcc [d:\vista_ldr\base\ntos\io\iomgr\ioverifier.c @ 1028]
8309399c 822ceb53 nt!IopfCompleteRequest+0x11d [d:\vista_ldr\base\ntos\io\iomgr\iosubs.c @ 3848]
83093a0c 8f7431f4 nt!IovCompleteRequest+0x11c [d:\vista_ldr\base\ntos\io\iomgr\ioverifier.c @ 946]
83093a20 8f74a7f6 usbhub!UsbhCompletePdoWakeIrp+0xaf [d:\vistartm\drivers\wdm\usb\hub\usbhub\pdopwr.c @ 1864]
83093a40 8f74a9e0 usbhub!UsbhPdoRemoveCleanup+0x3f [d:\vistartm\drivers\wdm\usb\hub\usbhub\pdo.c @ 1267]
83093a58 8f72e41e usbhub!UsbhPdoPnp_RemoveDevice+0x41 [d:\vistartm\drivers\wdm\usb\hub\usbhub\pdo.c @ 2152]
83093a74 8f726c92 usbhub!UsbhPdoPnp+0x78 [d:\vistartm\drivers\wdm\usb\hub\usbhub\pnp.c @ 1759]
83093a88 822ce681 usbhub!UsbhGenDispatch+0x4a [d:\vistartm\drivers\wdm\usb\hub\usbhub\hub.c @ 1116]
83093aac 82027f1c nt!IovCallDriver+0x252 [d:\vista_ldr\base\ntos\io\iomgr\ioverifier.c @ 574]
83093ac0 825cfce9 nt!IofCallDriver+0x1b [d:\vista_ldr\base\ntos\io\iomgr\iosubs.c @ 2370]
83093b08 822ce681 ndis!ndisPnPDispatch+0x4a4 [d:\vistartm\net\ndis\sys\ndispnp.c @ 1426]
83093b2c 82027f1c nt!IovCallDriver+0x252 [d:\vista_ldr\base\ntos\io\iomgr\ioverifier.c @ 574]
83093b40 821af73b nt!IofCallDriver+0x1b [d:\vista_ldr\base\ntos\io\iomgr\iosubs.c @ 2370]
83093b74 821af9a3 nt!IopSynchronousCall+0xce [d:\vista_ldr\base\ntos\io\pnpmgr\irp.c @ 215]
83093bd0 82006592 nt!IopRemoveDevice+0xd5 [d:\vista_ldr\base\ntos\io\pnpmgr\irp.c @ 663]
1: kd> kd 5
83093868 83093880
8309386c 8208fbf4 nt!_KiTrap0E+0xdc [d:\vista_ldr\base\ntos\ke\i386\trap.asm @ 5651]
83093870 00000001
83093874 9112ee50
83093878 00000000
1: kd> kbL
ChildEBP RetAddr Args to Child
83093868 8208fbf4 00000001 9112ee50 00000000 nt!MmAccessFault+0x106
83093868 82091f60 00000001 9112ee50 00000000 nt!_KiTrap0E+0xdc
830938f0 8fc9dbbb a78aae90 898b30b0 a78aaf00 nt!Exfi386InterlockedExchangeUlong
83093904 8204b2e7 89683700 898b3000 00000004 C7xUSBV3!powerWaitWakeCallback+0x1b
8309392c 822cec69 00000000 a78aae90 898b3000 nt!PopRequestCompletion+0x38
83093964 820acc1b 00000000 a78aae90 830939d4 nt!IovpLocalCompletionRoutine+0xcc
8309399c 822ceb53 a78aae90 896837b8 c0000120 nt!IopfCompleteRequest+0x11d
83093a0c 8f7431f4 c0000120 896837b8 89683700 nt!IovCompleteRequest+0x11c
83093a20 8f74a7f6 89522028 89683700 c0000120 usbhub!UsbhCompletePdoWakeIrp+0xaf
83093a40 8f74a9e0 89683700 a7834eb8 a7834fdc usbhub!UsbhPdoRemoveCleanup+0x3f
83093a58 8f72e41e 89683700 a7834eb8 a7834eb8 usbhub!UsbhPdoPnp_RemoveDevice+0x41
83093a74 8f726c92 89683700 a7834eb8 89683700 usbhub!UsbhPdoPnp+0x78
83093a88 822ce681 89683700 a7834eb8 a7834eb8 usbhub!UsbhGenDispatch+0x4a
83093aac 82027f1c 825cfce9 00000000 89683700 nt!IovCallDriver+0x252
83093ac0 825cfce9 a7834eb8 892f6030 875fce30 nt!IofCallDriver+0x1b
83093b08 822ce681 892f6030 00000002 a7835000 ndis!ndisPnPDispatch+0x4a4
83093b2c 82027f1c 821af73b 83093bcc 892f6030 nt!IovCallDriver+0x252
83093b40 821af73b 89683700 89301ea8 89683700 nt!IofCallDriver+0x1b
83093b74 821af9a3 89683700 83093ba8 00000000 nt!IopSynchronousCall+0xce
83093bd0 82006592 89683700 00000002 9f7d2510 nt!IopRemoveDevice+0xd5
1: kd> kvL
ChildEBP RetAddr Args to Child
83093868 8208fbf4 00000001 9112ee50 00000000 nt!MmAccessFault+0x106 (CONV: stdcall)
83093868 82091f60 00000001 9112ee50 00000000 nt!_KiTrap0E+0xdc (FPO: [0,0] TrapFrame @ 83093880) (CONV: cdecl)
830938f0 8fc9dbbb a78aae90 898b30b0 a78aaf00 nt!Exfi386InterlockedExchangeUlong (FPO: [0,0,0])
83093904 8204b2e7 89683700 898b3000 00000004 C7xUSBV3!powerWaitWakeCallback+0x1b (FPO: [Non-Fpo]) (CONV: stdcall)
8309392c 822cec69 00000000 a78aae90 898b3000 nt!PopRequestCompletion+0x38 (CONV: stdcall)
83093964 820acc1b 00000000 a78aae90 830939d4 nt!IovpLocalCompletionRoutine+0xcc (CONV: stdcall)
8309399c 822ceb53 a78aae90 896837b8 c0000120 nt!IopfCompleteRequest+0x11d (CONV: fastcall)
83093a0c 8f7431f4 c0000120 896837b8 89683700 nt!IovCompleteRequest+0x11c (CONV: fastcall)
83093a20 8f74a7f6 89522028 89683700 c0000120 usbhub!UsbhCompletePdoWakeIrp+0xaf (FPO: [Non-Fpo]) (CONV: stdcall)
83093a40 8f74a9e0 89683700 a7834eb8 a7834fdc usbhub!UsbhPdoRemoveCleanup+0x3f (FPO: [Non-Fpo]) (CONV: stdcall)
83093a58 8f72e41e 89683700 a7834eb8 a7834eb8 usbhub!UsbhPdoPnp_RemoveDevice+0x41 (FPO: [Non-Fpo]) (CONV: stdcall)
83093a74 8f726c92 89683700 a7834eb8 89683700 usbhub!UsbhPdoPnp+0x78 (FPO: [Non-Fpo]) (CONV: stdcall)
83093a88 822ce681 89683700 a7834eb8 a7834eb8 usbhub!UsbhGenDispatch+0x4a (FPO: [Non-Fpo]) (CONV: stdcall)
83093aac 82027f1c 825cfce9 00000000 89683700 nt!IovCallDriver+0x252 (CONV: fastcall)
83093ac0 825cfce9 a7834eb8 892f6030 875fce30 nt!IofCallDriver+0x1b (CONV: fastcall)
83093b08 822ce681 892f6030 00000002 a7835000 ndis!ndisPnPDispatch+0x4a4 (FPO: [Non-Fpo]) (CONV: stdcall)
83093b2c 82027f1c 821af73b 83093bcc 892f6030 nt!IovCallDriver+0x252 (CONV: fastcall)
83093b40 821af73b 89683700 89301ea8 89683700 nt!IofCallDriver+0x1b (CONV: fastcall)
83093b74 821af9a3 89683700 83093ba8 00000000 nt!IopSynchronousCall+0xce (CONV: stdcall)
83093bd0 82006592 89683700 00000002 9f7d2510 nt!IopRemoveDevice+0xd5 (CONV: stdcall)
1: kd> kpL
ChildEBP RetAddr
83093868 8208fbf4 nt!MmAccessFault(unsigned long FaultStatus = 1, void * VirtualAddress = 0x9112ee50, char PreviousMode = 0 '', void * TrapInformation = 0x83093880)+0x106
83093868 82091f60 nt!_KiTrap0E(void)+0xdc
830938f0 8fc9dbbb nt!Exfi386InterlockedExchangeUlong(void)
83093904 8204b2e7 C7xUSBV3!powerWaitWakeCallback(struct _DEVICE_OBJECT * Object = 0x89683700, unsigned char MinorFunction = 0x00 '', union _POWER_STATE PowerState = union _POWER_STATE, struct _MINIPORT_ADAPTER * Adapter = 0x9112eb50, struct _IO_STATUS_BLOCK * IoStatus = 0xa78aaea8)+0x1b
8309392c 822cec69 nt!PopRequestCompletion(struct _DEVICE_OBJECT * DeviceObject = 0x00000000, struct _IRP * Irp = 0xa78aae90, void * Context = 0x898b3000)+0x38
83093964 820acc1b nt!IovpLocalCompletionRoutine(struct _DEVICE_OBJECT * DeviceObject = 0x00000000, struct _IRP * Irp = 0xa78aae90, void * Context = 0x830939d4)+0xcc
8309399c 822ceb53 nt!IopfCompleteRequest(struct _IRP * Irp = 0x9112ee50, char PriorityBoost = 0 '')+0x11d
83093a0c 8f7431f4 nt!IovCompleteRequest(struct _IRP * Irp = 0x9112ee50, char PriorityBoost = 0 '')+0x11c
83093a20 8f74a7f6 usbhub!UsbhCompletePdoWakeIrp(struct _DEVICE_OBJECT * HubFdo = 0x89522028, struct _DEVICE_OBJECT * Pdo = 0x89683700, long NtStatus = -1073741536)+0xaf
83093a40 8f74a9e0 usbhub!UsbhPdoRemoveCleanup(struct _DEVICE_OBJECT * Pdo = 0x89683700)+0x3f
83093a58 8f72e41e usbhub!UsbhPdoPnp_RemoveDevice(struct _DEVICE_OBJECT * Pdo = 0x89683700, struct _IRP * Irp = 0xa7834eb8)+0x41
83093a74 8f726c92 usbhub!UsbhPdoPnp(struct _DEVICE_OBJECT * HubPdo = 0x89683700, struct _IRP * Irp = 0xa7834eb8)+0x78
83093a88 822ce681 usbhub!UsbhGenDispatch(struct _DEVICE_OBJECT * DeviceObject = 0x89683700, struct _IRP * Irp = 0xa7834eb8)+0x4a
83093aac 82027f1c nt!IovCallDriver(struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50, struct _IRP * Irp = 0x00000000, void * ReturnAddress = 0x825cfce9)+0x252
83093ac0 825cfce9 nt!IofCallDriver(struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50, struct _IRP * Irp = 0x00000000)+0x1b
83093b08 822ce681 ndis!ndisPnPDispatch(struct _DEVICE_OBJECT * DeviceObject = 0x892f6030, struct _IRP * Irp = 0x00000002)+0x4a4
83093b2c 82027f1c nt!IovCallDriver(struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50, struct _IRP * Irp = 0x00000000, void * ReturnAddress = 0x821af73b)+0x252
83093b40 821af73b nt!IofCallDriver(struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50, struct _IRP * Irp = 0x00000000)+0x1b
83093b74 821af9a3 nt!IopSynchronousCall(struct _DEVICE_OBJECT * DeviceObject = 0x89683700, struct _IO_STACK_LOCATION * TopStackLocation = 0x83093ba8, long DefaultStatus = -1882596448, unsigned long DefaultInformation = 0x83093bd0, unsigned long * Information = 0x00000000)+0xce
83093bd0 82006592 nt!IopRemoveDevice(struct _DEVICE_OBJECT * TargetDevice = 0x89683700, unsigned long IrpMinorCode = 2)+0xd5
1: kd> kPL
ChildEBP RetAddr
83093868 8208fbf4 nt!MmAccessFault(
unsigned long FaultStatus = 1,
void * VirtualAddress = 0x9112ee50,
char PreviousMode = 0 '',
void * TrapInformation = 0x83093880)+0x106
83093868 82091f60 nt!_KiTrap0E(void)+0xdc
830938f0 8fc9dbbb nt!Exfi386InterlockedExchangeUlong(void)
83093904 8204b2e7 C7xUSBV3!powerWaitWakeCallback(
struct _DEVICE_OBJECT * Object = 0x89683700,
unsigned char MinorFunction = 0x00 '',
union _POWER_STATE PowerState = union _POWER_STATE,
struct _MINIPORT_ADAPTER * Adapter = 0x9112eb50,
struct _IO_STATUS_BLOCK * IoStatus = 0xa78aaea8)+0x1b
8309392c 822cec69 nt!PopRequestCompletion(
struct _DEVICE_OBJECT * DeviceObject = 0x00000000,
struct _IRP * Irp = 0xa78aae90,
void * Context = 0x898b3000)+0x38
83093964 820acc1b nt!IovpLocalCompletionRoutine(
struct _DEVICE_OBJECT * DeviceObject = 0x00000000,
struct _IRP * Irp = 0xa78aae90,
void * Context = 0x830939d4)+0xcc
8309399c 822ceb53 nt!IopfCompleteRequest(
struct _IRP * Irp = 0x9112ee50,
char PriorityBoost = 0 '')+0x11d
83093a0c 8f7431f4 nt!IovCompleteRequest(
struct _IRP * Irp = 0x9112ee50,
char PriorityBoost = 0 '')+0x11c
83093a20 8f74a7f6 usbhub!UsbhCompletePdoWakeIrp(
struct _DEVICE_OBJECT * HubFdo = 0x89522028,
struct _DEVICE_OBJECT * Pdo = 0x89683700,
long NtStatus = -1073741536)+0xaf
83093a40 8f74a9e0 usbhub!UsbhPdoRemoveCleanup(
struct _DEVICE_OBJECT * Pdo = 0x89683700)+0x3f
83093a58 8f72e41e usbhub!UsbhPdoPnp_RemoveDevice(
struct _DEVICE_OBJECT * Pdo = 0x89683700,
struct _IRP * Irp = 0xa7834eb8)+0x41
83093a74 8f726c92 usbhub!UsbhPdoPnp(
struct _DEVICE_OBJECT * HubPdo = 0x89683700,
struct _IRP * Irp = 0xa7834eb8)+0x78
83093a88 822ce681 usbhub!UsbhGenDispatch(
struct _DEVICE_OBJECT * DeviceObject = 0x89683700,
struct _IRP * Irp = 0xa7834eb8)+0x4a
83093aac 82027f1c nt!IovCallDriver(
struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50,
struct _IRP * Irp = 0x00000000,
void * ReturnAddress = 0x825cfce9)+0x252
83093ac0 825cfce9 nt!IofCallDriver(
struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50,
struct _IRP * Irp = 0x00000000)+0x1b
83093b08 822ce681 ndis!ndisPnPDispatch(
struct _DEVICE_OBJECT * DeviceObject = 0x892f6030,
struct _IRP * Irp = 0x00000002)+0x4a4
83093b2c 82027f1c nt!IovCallDriver(
struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50,
struct _IRP * Irp = 0x00000000,
void * ReturnAddress = 0x821af73b)+0x252
83093b40 821af73b nt!IofCallDriver(
struct _DEVICE_OBJECT * DeviceObject = 0x9112ee50,
struct _IRP * Irp = 0x00000000)+0x1b
83093b74 821af9a3 nt!IopSynchronousCall(
struct _DEVICE_OBJECT * DeviceObject = 0x89683700,
struct _IO_STACK_LOCATION * TopStackLocation = 0x83093ba8,
long DefaultStatus = -1882596448,
unsigned long DefaultInformation = 0x83093bd0,
unsigned long * Information = 0x00000000)+0xce
83093bd0 82006592 nt!IopRemoveDevice(
struct _DEVICE_OBJECT * TargetDevice = 0x89683700,
unsigned long IrpMinorCode = 2)+0xd5
1: kd> kfL
Memory ChildEBP RetAddr
83093868 8208fbf4 nt!MmAccessFault+0x106
0 83093868 82091f60 nt!_KiTrap0E+0xdc
88 830938f0 8fc9dbbb nt!Exfi386InterlockedExchangeUlong
14 83093904 8204b2e7 C7xUSBV3!powerWaitWakeCallback+0x1b
28 8309392c 822cec69 nt!PopRequestCompletion+0x38
38 83093964 820acc1b nt!IovpLocalCompletionRoutine+0xcc
38 8309399c 822ceb53 nt!IopfCompleteRequest+0x11d
70 83093a0c 8f7431f4 nt!IovCompleteRequest+0x11c
14 83093a20 8f74a7f6 usbhub!UsbhCompletePdoWakeIrp+0xaf
20 83093a40 8f74a9e0 usbhub!UsbhPdoRemoveCleanup+0x3f
18 83093a58 8f72e41e usbhub!UsbhPdoPnp_RemoveDevice+0x41
1c 83093a74 8f726c92 usbhub!UsbhPdoPnp+0x78
14 83093a88 822ce681 usbhub!UsbhGenDispatch+0x4a
24 83093aac 82027f1c nt!IovCallDriver+0x252
14 83093ac0 825cfce9 nt!IofCallDriver+0x1b
48 83093b08 822ce681 ndis!ndisPnPDispatch+0x4a4
24 83093b2c 82027f1c nt!IovCallDriver+0x252
14 83093b40 821af73b nt!IofCallDriver+0x1b
34 83093b74 821af9a3 nt!IopSynchronousCall+0xce
5c 83093bd0 82006592 nt!IopRemoveDevice+0xd5