windbg调试学习笔记(二)

3 进程与线程

既可以显示进程和线程列表,又可以显示指定进程或线程的详细信息。调试命令可以提供比taskmgr更详尽的进程资料,在调试过程中不可或缺。

3.1 进程命令

进程命令包括这些内容:显示进程列表、进程环境块、设置进程环境。

进程列表

多个命令可显示进程列表,但一般只能在特定情况下使用,它们是:|、.tlist、!process和!dml_proc。

竖线命令显示当前被调试进程列表的状态信息,这个命令在本章开头已作过介绍,命令格式如下:

§  |  [进程号]

请注意这里的定语:被调试进程列表。大多数情况下调试器中只有一个被调试进程,但可以通过.attach或者.create命令同时挂载或创建多个调试对象。当同时对多个进程调试时,进程号是从0开始的整数。下图中显示了两个被调试的进程。

0:004> |
.  0 id: 1c80 examine name: C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe


§  .tlist [选项] [模块名]

           .tlist命令显示当前系统中的进程列表,他是目前唯一可在用户模式下显示系统当前进程列表的命令。它有两个可选项:-v显示进程详细信息,-c只显示当前进程信息。


         内核模式下同样可以使用.tlist,但更好的命令是!process。!process在内核模式下显示进程列表,和指定进程的详细信息,也能显示进程中的线程和调用栈内容。典型格式如下:

§  !process: 显示调试器当前运行进程信息


0:004> !dml_proc 0x0
DbgId  PID    Image file name
0      1c80   ...\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe


Browse module list


Threads:
    DbgId  TID    Name (if available)
    0      2edc   <No name>
    1      7274   <No name>
    2      84f0   <No name>
    3      85ec   <No name>
    4      bf78   <No name>
    5      1674   <No name>


此外,还有一个DML版本的进程列表命令,如下:

§  !dml_proc [进程号|进程地址]

此命令可以看成“|”和“!process”命令的DML合并版本,可在用户与内核模式下使用。显示的进程信息偏重于线程和调用栈。用户模式下此命令和“|”一样,只能显示被调试进程的信息。右图是内核模式下使用此命令的效果:


进程信息

进程环境块(Process Enviroment Block)是内核结构体,使用!peb命令参看其信息,但也可以用dt命令查看完整的结构体定义。格式如下:

§  !peb  [地址]

如果未设置PEB地址,则默认为当前进程。内核模式下可通过!process命令获取PEB结构体地址;用户模式下只能显示当前进程的PEB信息,故而一般不带参数。



0:004> !peb
PEB at 0000000000aff000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         00007ff7160d0000
    Ldr                       00007ffe7144b340
    Ldr.Initialized:          Yes
    Ldr.InInitializationOrderModuleList: 0000000002db28b0 . 0000000002db4b50
    Ldr.InLoadOrderModuleList:           0000000002db2a60 . 0000000002dbbc90
    Ldr.InMemoryOrderModuleList:         0000000002db2a70 . 0000000002dbbca0
                    Base TimeStamp                     Module
            7ff7160d0000 5a449c9b Dec 28 15:26:19 2017 C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe
            7ffe712f0000 8274fd8b May 11 13:39:23 2039 C:\Windows\SYSTEM32\ntdll.dll
            7ffe6f2a0000 f5fa43df Oct 10 10:41:35 2100 C:\Windows\System32\KERNEL32.DLL
            7ffe6e330000 1a9bbe0b Feb 24 03:59:07 1984 C:\Windows\System32\KERNELBASE.dll
                72c60000 488ef62b Jul 29 18:51:23 2008 C:\Windows\WinSxS\amd64_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_737233ca1c100ce5\MSVCP90D.dll
                72d80000 488ef626 Jul 29 18:51:18 2008 C:\Windows\WinSxS\amd64_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_737233ca1c100ce5\MSVCR90D.dll
                6fd20000 53828c7e May 26 08:36:14 2014 C:\Qt\4.8.4\bin\QtGuid4.dll
                70fd0000 53828953 May 26 08:22:43 2014 C:\Qt\4.8.4\bin\QtCored4.dll
            7ffe6ef30000 6d9de53a Apr 11 19:12:58 2028 C:\Windows\System32\USER32.dll
            7ffe6faf0000 efcc154c Jun 27 07:57:00 2097 C:\Windows\System32\GDI32.dll
            7ffe6e6e0000 d9592a17 Jul 21 04:29:11 2085 C:\Windows\System32\win32u.dll
            7ffe6e1a0000 298bec01 Feb 02 21:02:57 1992 C:\Windows\System32\gdi32full.dll
            7ffe6e700000 d867caf3 Jan 19 02:26:59 2085 C:\Windows\System32\msvcp_win.dll
            7ffe6ed40000 cf17fc6c Feb 06 22:34:20 2080 C:\Windows\System32\ole32.dll
            7ffe6e580000 8ac9f9d4 Oct 15 11:28:20 2043 C:\Windows\System32\ucrtbase.dll
            7ffe6f590000 b66dc19d Dec 27 11:31:41 2066 C:\Windows\System32\combase.dll
            7ffe6fd80000 20fe5196 Jul 18 00:32:22 1987 C:\Windows\System32\RPCRT4.dll
            7ffe6f080000 64f6792a Sep 05 08:41:14 2023 C:\Windows\System32\COMDLG32.dll
            7ffe6df10000 535124ab Apr 18 21:12:11 2014 C:\Windows\System32\bcryptPrimitives.dll
            7ffe6ee90000 3280d1b7 Nov 07 01:58:15 1996 C:\Windows\System32\msvcrt.dll
            7ffe6f960000 b4c11302 Feb 05 07:36:34 2066 C:\Windows\System32\sechost.dll
            7ffe6ec90000 a64bfd9f May 30 23:26:23 2058 C:\Windows\System32\shcore.dll
            7ffe6f8b0000 46b92c26 Aug 08 10:36:22 2007 C:\Windows\System32\ADVAPI32.dll
            7ffe6f190000 166c812d Dec 03 14:41:49 1981 C:\Windows\System32\SHLWAPI.dll
            7ffe6f380000 60cde072 Jun 19 20:17:54 2021 C:\Windows\System32\WS2_32.dll
            7ffe6feb0000 c3faa15c Mar 11 16:27:08 2074 C:\Windows\System32\SHELL32.dll
            7ffe6df80000 bb524065 Aug 03 12:30:29 2069 C:\Windows\System32\cfgmgr32.dll
            7ffe6d810000 c007cd3b Feb 03 22:52:43 2072 C:\Windows\System32\windows.storage.dll
            7ffe488d0000 8b5b80d8 Feb 02 20:43:04 2044 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_5.82.15063.413_none_0e0f5dcc67adff4e\COMCTL32.dll
            7ffe6d7d0000 ed031ad5 Jan 03 12:34:29 2096 C:\Windows\System32\kernel.appcore.dll
            7ffe6d780000 bc0704c4 Dec 18 15:16:20 2069 C:\Windows\System32\powrprof.dll
            7ffe6d760000 c8e1d59a Oct 18 18:44:42 2076 C:\Windows\System32\profapi.dll
            7ffe6f9d0000 98823ee8 Jan 30 14:23:36 2051 C:\Windows\System32\OLEAUT32.dll
            7ffe6f350000 dd2e6bc9 Aug 04 11:43:05 2087 C:\Windows\System32\IMM32.dll
            7ffe44480000 b555e731 May 29 04:57:21 2066 C:\Windows\SYSTEM32\WINSPOOL.DRV
            7ffe6c290000 24ec155f Aug 18 21:55:43 1989 C:\Windows\SYSTEM32\WINMM.dll
            7ffe6c260000 318335b4 Apr 28 17:09:08 1996 C:\Windows\SYSTEM32\WINMMBASE.dll
            7ffe6d400000 17fe17fb Oct 04 05:24:11 1982 C:\Windows\SYSTEM32\bcrypt.dll
    SubSystemData:     0000000000000000
    ProcessHeap:       0000000002db0000
    ProcessParameters: 0000000002db1f00
    CurrentDirectory:  'C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\'
    WindowTitle:  'C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe'
    ImageFile:    'C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe'
    CommandLine:  '"C:\Users\winne\Documents\Visual Studio 2008\Projects\ttt\x64\Debug\ttt.exe" '
    DllPath:      '< Name not readable >'
    Environment:  0000000002db10d0
        =::=::\
        ALLUSERSPROFILE=C:\ProgramData
        APPDATA=C:\Users\winne\AppData\Roaming
        CommonProgramFiles=C:\Program Files\Common Files
        CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
        CommonProgramW6432=C:\Program Files\Common Files
        COMPUTERNAME=DESKTOP-IUA9ONQ
        ComSpec=C:\Windows\system32\cmd.exe
        DEVELOP_HOME=D:\D6000-Develop\V2.0\source
        HOMEDRIVE=C:
        HOMEPATH=\Users\winne
        LOCALAPPDATA=C:\Users\winne\AppData\Local
        LOGONSERVER=\\DESKTOP-IUA9ONQ
        NBENV=D:\d6000\d6000\d6000
        NUMBER_OF_PROCESSORS=8
        OneDrive=C:\Users\winne\OneDrive
        ORACLE_HOME=f:\oracle\product\11.2.0\dbhome_1
        OS=Windows_NT
        Path=f:\oracle\product\11.2.0\dbhome_1\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Qt\4.8.4\\bin;C:\Qt\4.8.4\\lib;c:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;D:\d6000\d6000\d6000\bin;D:\d6000\d6000\d6000\dll;D:\d6000\d6000\d6000\protocol;C:\Users\winne\AppData\Local\Microsoft\WindowsApps;
        PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
        PROCESSOR_ARCHITECTURE=AMD64
        PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
        PROCESSOR_LEVEL=6
        PROCESSOR_REVISION=3a09
        ProgramData=C:\ProgramData
        ProgramFiles=C:\Program Files
        ProgramFiles(x86)=C:\Program Files (x86)
        ProgramW6432=C:\Program Files
        PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
        PUBLIC=C:\Users\Public
        QTDIR=C:\Qt\4.8.4\
        SESSIONNAME=Console
        SystemDrive=C:
        SystemRoot=C:\Windows
        TEMP=C:\Users\winne\AppData\Local\Temp
        TMP=C:\Users\winne\AppData\Local\Temp
        USERDOMAIN=DESKTOP-IUA9ONQ
        USERDOMAIN_ROAMINGPROFILE=DESKTOP-IUA9ONQ
        USERNAME=Jack-PC
        USERPROFILE=C:\Users\winne
        VS90COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\
        windir=C:\Windows


§  dt  nt!_peb  地址

此命令显示系统nt模块中所定义的内核结构体PEB详细内容。使用之前必须先熟悉结构体定义。


0:004> dt  nt!_peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit
   +0x003 IsImageDynamicallyRelocated : Pos 2, 1 Bit
   +0x003 SkipPatchingUser32Forwarders : Pos 3, 1 Bit
   +0x003 IsPackagedProcess : Pos 4, 1 Bit
   +0x003 IsAppContainer   : Pos 5, 1 Bit
   +0x003 IsProtectedProcessLight : Pos 6, 1 Bit
   +0x003 IsLongPathAwareProcess : Pos 7, 1 Bit
   +0x004 Padding0         : [4] UChar
   +0x008 Mutant           : Ptr64 Void
   +0x010 ImageBaseAddress : Ptr64 Void
   +0x018 Ldr              : Ptr64 _PEB_LDR_DATA
   +0x020 ProcessParameters : Ptr64 _RTL_USER_PROCESS_PARAMETERS
   +0x028 SubSystemData    : Ptr64 Void
   +0x030 ProcessHeap      : Ptr64 Void
   +0x038 FastPebLock      : Ptr64 _RTL_CRITICAL_SECTION
   +0x040 AtlThunkSListPtr : Ptr64 _SLIST_HEADER
   +0x048 IFEOKey          : Ptr64 Void
   +0x050 CrossProcessFlags : Uint4B
   +0x050 ProcessInJob     : Pos 0, 1 Bit
   +0x050 ProcessInitializing : Pos 1, 1 Bit
   +0x050 ProcessUsingVEH  : Pos 2, 1 Bit
   +0x050 ProcessUsingVCH  : Pos 3, 1 Bit
   +0x050 ProcessUsingFTH  : Pos 4, 1 Bit
   +0x050 ProcessPreviouslyThrottled : Pos 5, 1 Bit
   +0x050 ProcessCurrentlyThrottled : Pos 6, 1 Bit
   +0x050 ReservedBits0    : Pos 7, 25 Bits
   +0x054 Padding1         : [4] UChar
   +0x058 KernelCallbackTable : Ptr64 Void
   +0x058 UserSharedInfoPtr : Ptr64 Void
   +0x060 SystemReserved   : [1] Uint4B
   +0x064 AtlThunkSListPtr32 : Uint4B
   +0x068 ApiSetMap        : Ptr64 Void
   +0x070 TlsExpansionCounter : Uint4B
   +0x074 Padding2         : [4] UChar
   +0x078 TlsBitmap        : Ptr64 Void
   +0x080 TlsBitmapBits    : [2] Uint4B
   +0x088 ReadOnlySharedMemoryBase : Ptr64 Void
   +0x090 SharedData       : Ptr64 Void
   +0x098 ReadOnlyStaticServerData : Ptr64 Ptr64 Void
   +0x0a0 AnsiCodePageData : Ptr64 Void
   +0x0a8 OemCodePageData  : Ptr64 Void
   +0x0b0 UnicodeCaseTableData : Ptr64 Void
   +0x0b8 NumberOfProcessors : Uint4B
   +0x0bc NtGlobalFlag     : Uint4B
   +0x0c0 CriticalSectionTimeout : _LARGE_INTEGER
   +0x0c8 HeapSegmentReserve : Uint8B
   +0x0d0 HeapSegmentCommit : Uint8B
   +0x0d8 HeapDeCommitTotalFreeThreshold : Uint8B
   +0x0e0 HeapDeCommitFreeBlockThreshold : Uint8B
   +0x0e8 NumberOfHeaps    : Uint4B
   +0x0ec MaximumNumberOfHeaps : Uint4B
   +0x0f0 ProcessHeaps     : Ptr64 Ptr64 Void
   +0x0f8 GdiSharedHandleTable : Ptr64 Void
   +0x100 ProcessStarterHelper : Ptr64 Void
   +0x108 GdiDCAttributeList : Uint4B
   +0x10c Padding3         : [4] UChar
   +0x110 LoaderLock       : Ptr64 _RTL_CRITICAL_SECTION
   +0x118 OSMajorVersion   : Uint4B
   +0x11c OSMinorVersion   : Uint4B
   +0x120 OSBuildNumber    : Uint2B
   +0x122 OSCSDVersion     : Uint2B
   +0x124 OSPlatformId     : Uint4B
   +0x128 ImageSubsystem   : Uint4B
   +0x12c ImageSubsystemMajorVersion : Uint4B
   +0x130 ImageSubsystemMinorVersion : Uint4B
   +0x134 Padding4         : [4] UChar
   +0x138 ActiveProcessAffinityMask : Uint8B
   +0x140 GdiHandleBuffer  : [60] Uint4B
   +0x230 PostProcessInitRoutine : Ptr64     void 
   +0x238 TlsExpansionBitmap : Ptr64 Void
   +0x240 TlsExpansionBitmapBits : [32] Uint4B
   +0x2c0 SessionId        : Uint4B
   +0x2c4 Padding5         : [4] UChar
   +0x2c8 AppCompatFlags   : _ULARGE_INTEGER
   +0x2d0 AppCompatFlagsUser : _ULARGE_INTEGER
   +0x2d8 pShimData        : Ptr64 Void
   +0x2e0 AppCompatInfo    : Ptr64 Void
   +0x2e8 CSDVersion       : _UNICODE_STRING
   +0x2f8 ActivationContextData : Ptr64 _ACTIVATION_CONTEXT_DATA
   +0x300 ProcessAssemblyStorageMap : Ptr64 _ASSEMBLY_STORAGE_MAP
   +0x308 SystemDefaultActivationContextData : Ptr64 _ACTIVATION_CONTEXT_DATA
   +0x310 SystemAssemblyStorageMap : Ptr64 _ASSEMBLY_STORAGE_MAP
   +0x318 MinimumStackCommit : Uint8B
   +0x320 FlsCallback      : Ptr64 _FLS_CALLBACK_INFO
   +0x328 FlsListHead      : _LIST_ENTRY
   +0x338 FlsBitmap        : Ptr64 Void
   +0x340 FlsBitmapBits    : [4] Uint4B
   +0x350 FlsHighIndex     : Uint4B
   +0x358 WerRegistrationData : Ptr64 Void
   +0x360 WerShipAssertPtr : Ptr64 Void
   +0x368 pUnused          : Ptr64 Void
   +0x370 pImageHeaderHash : Ptr64 Void
   +0x378 TracingFlags     : Uint4B
   +0x378 HeapTracingEnabled : Pos 0, 1 Bit
   +0x378 CritSecTracingEnabled : Pos 1, 1 Bit
   +0x378 LibLoaderTracingEnabled : Pos 2, 1 Bit
   +0x378 SpareTracingBits : Pos 3, 29 Bits
   +0x37c Padding6         : [4] UChar
   +0x380 CsrServerReadOnlySharedMemoryBase : Uint8B
   +0x388 TppWorkerpListLock : Uint8B
   +0x390 TppWorkerpList   : _LIST_ENTRY
   +0x3a0 WaitOnAddressHashTable : [128] Ptr64 Void


进程切换

进程环境的切换,将伴随着与进程相关的寄存器、堆栈的切换。在不同进程环境中进行的调试结果有天壤之别。上文在讲“|”命令的时候,讲过用户环境下多进程间如何互相切换,使用命令:

§  |  [进程号]  s

那么内核模式下,情况又不同了。内核模式下的进程切换,不同于用户模式下的被调试进程间切换,而是系统存在的多进程间切换。内核环境下,以进程地址作为参数,调用如下命令以进行进程环境切换:

§  .process [进程地址]

如果不使用任何参数,.process命令将显示当前进程地址。所谓进程地址,即ERPCESS结构体地址。

或以页目录地址为参数,调用下面命令切换用户地址空间:

§  .context [页目录地址]

如果不使用任何参数,.context命令将显示当前页目录地址。页目录地址就是!process命令中显示的DirBase值。

进程切换后,为了检测是否正确切换,可再用!peb命令检查当前进程的环境信息。


线程命令

命令“~”能够进行线程相关的操作。不带任何参数的情况下,它列出当前调试进程的线程。下图是计算器进程某时刻的线程列表:

0:004> ~
   0  Id: 1c80.2edc Suspend: 1 Teb: 00000000`00b00000 Unfrozen
   1  Id: 1c80.7274 Suspend: 1 Teb: 00000000`00b02000 Unfrozen
   2  Id: 1c80.84f0 Suspend: 1 Teb: 00000000`00b04000 Unfrozen
   3  Id: 1c80.85ec Suspend: 1 Teb: 00000000`00b06000 Unfrozen
.  4  Id: 1c80.bf78 Suspend: 1 Teb: 00000000`00b0a000 Unfrozen
   5  Id: 1c80.1674 Suspend: 1 Teb: 00000000`00b0c000 Unfrozen


线程冰冻

参数f与u分别代表freeze和unfress,前者是指冻住指定线程,后者将被冰冻线程解冻。

§  ~2f

表示把2号线程冻住,在解冻之前,不再分发CPU时间给它。

若要让指定线程重新运行,需使用参数u:

§  ~2u

针对这两个命令,下面有一个小实验

运行Windbg,并选择调试记事本程序(Notepad.exe)。程序起来后,CTL+BREAK中断程序运行,输入命令:

 

~0f

 

再输入g命令让记事本继续运行。

 

此时尝试用鼠标定位到notepad软件,发现软件界面无法被定位、移动、最大小化,甚至“清空桌面”操作也无济于事。这是因为0号线程为notepad的主线程,被冻住后整个软件都失去响应。

 

更严重的是,“清空桌面”操作(Win + D)也会失效,应是Notepad拒绝响应的缘故。

 

线程挂起

 

参数n和m分别代表increase和resume,前者增加一个线程挂起计数,后者减少一个线程挂起计数。如果两次增加线程挂起计数(即达到2),则必须两次resume才能让线程恢复到运行状态。


把上面实验中的~0f命令改变成~0n,也能达到相似的效果。


线程切换

查看指定线程的信息,用下面的命令:

§  ~ 线程号

线程号是由调试器软件内部维护的线程ID值,是一个从0开始的整数,和线程ID不是一回事。

线程信息中包括有线程环境块地址,可通过!teb命令查看环境块信息:

§  !teb  [teb地址]

如要在多线程间作切换,需使用~命令的s参数:

§  ~  线程号 s

由于线程号在外部是没有太大意义的,所以另一个线程切换命令是以线程ID来标识一个线程的。这个命令比较奇怪,以双波浪线打头,格式如下:

§  ~~[线程ID]  s

注意这个命令中的[]并非可选符,而是命令的一部分。例如命令:~~[11a0] s,它将当前线程切换到线程ID为0x11a0的线程。线程ID是系统维护的系统唯一的ID值。

0:001> ~
   0  Id: 1c80.2edc Suspend: 1 Teb: 00000000`00b00000 Unfrozen
.  1  Id: 1c80.7274 Suspend: 1 Teb: 00000000`00b02000 Unfrozen
   2  Id: 1c80.84f0 Suspend: 1 Teb: 00000000`00b04000 Unfrozen
   3  Id: 1c80.85ec Suspend: 1 Teb: 00000000`00b06000 Unfrozen
#  4  Id: 1c80.bf78 Suspend: 1 Teb: 00000000`00b0a000 Unfrozen
   5  Id: 1c80.1674 Suspend: 1 Teb: 00000000`00b0c000 Unfrozen


0:001> ~~[85ec]s
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret


0:003> ~
   0  Id: 1c80.2edc Suspend: 1 Teb: 00000000`00b00000 Unfrozen
   1  Id: 1c80.7274 Suspend: 1 Teb: 00000000`00b02000 Unfrozen
   2  Id: 1c80.84f0 Suspend: 1 Teb: 00000000`00b04000 Unfrozen
.  3  Id: 1c80.85ec Suspend: 1 Teb: 00000000`00b06000 Unfrozen
#  4  Id: 1c80.bf78 Suspend: 1 Teb: 00000000`00b0a000 Unfrozen
   5  Id: 1c80.1674 Suspend: 1 Teb: 00000000`00b0c000 Unfrozen


第一个命令“~”运行时,当前线程是14号线程,请注意1号线程前面有一小点;运行第二个命令,将当前线程切换为3号线程;为了检验结果,再次运行“~”命令,此时注意到小点移到9号线程前,表明9号线程为当前线程。 


§  ~*k

显示所有线程栈信息(此命令意指:对所有线程执行k指令)。下图中,当前进程共包含两个线程,显示了这两个线程各自的栈信息:



0:003> ~*k


   0  Id: 1c80.2edc Suspend: 1 Teb: 00000000`00b00000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`00d3f528 00007ffe`6e37dcb0 ntdll!ZwWaitForMultipleObjects+0x14
00000000`00d3f530 00007ffe`6e37dbae KERNELBASE!WaitForMultipleObjectsEx+0xf0
00000000`00d3f830 00007ff7`160d164c KERNELBASE!WaitForMultipleObjects+0xe
00000000`00d3f870 00007ff7`160d65e1 ttt!main+0x11c [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 49]
00000000`00d3f8f0 00007ff7`160d5de2 ttt!WinMain+0xb1 [c:\qt\4.8.4\src\winmain\qtmain_win.cpp @ 131]
00000000`00d3f960 00007ff7`160d5ade ttt!__tmainCRTStartup+0x2f2 [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 578]
00000000`00d3fa50 00007ffe`6f2b2774 ttt!WinMainCRTStartup+0xe [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 403]
00000000`00d3fa80 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`00d3fab0 00000000`00000000 ntdll!RtlUserThreadStart+0x21


   1  Id: 1c80.7274 Suspend: 1 Teb: 00000000`00b02000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`0307fc18 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0307fc20 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0307ff30 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0307ff60 00000000`00000000 ntdll!RtlUserThreadStart+0x21


   2  Id: 1c80.84f0 Suspend: 1 Teb: 00000000`00b04000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`0317f828 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0317f830 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0317fb40 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0317fb70 00000000`00000000 ntdll!RtlUserThreadStart+0x21


   3  Id: 1c80.85ec Suspend: 1 Teb: 00000000`00b06000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`0327f508 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0327f510 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0327f820 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0327f850 00000000`00000000 ntdll!RtlUserThreadStart+0x21


#  4  Id: 1c80.bf78 Suspend: 1 Teb: 00000000`00b0a000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`052bfd20 00007ffe`6f2b2774 ttt!ReadRoutine+0xab [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 20]
00000000`052bfdc0 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`052bfdf0 00000000`00000000 ntdll!RtlUserThreadStart+0x21


   5  Id: 1c80.1674 Suspend: 1 Teb: 00000000`00b0c000 Unfrozen
Child-SP          RetAddr           Call Site
00000000`053bf800 00007ff7`160d3126 ttt!std::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>+0xe
00000000`053bf830 00007ff7`160d23e7 ttt!std::_Vector_const_iterator<int * __ptr64,std::allocator<int * __ptr64> >::_Vector_const_iterator<int * __ptr64,std::allocator<int * __ptr64> >+0x26 [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 68]
00000000`053bf880 00007ff7`160d1aee ttt!std::_Vector_iterator<int * __ptr64,std::allocator<int * __ptr64> >::_Vector_iterator<int * __ptr64,std::allocator<int * __ptr64> >+0x27 [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 322]
00000000`053bf8b0 00007ff7`160d1788 ttt!std::vector<int * __ptr64,std::allocator<int * __ptr64> >::end+0x2e [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 651]
00000000`053bf8f0 00007ffe`6f2b2774 ttt!WriteRoutine+0x38 [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 28]
00000000`053bf980 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`053bf9b0 00000000`00000000 ntdll!RtlUserThreadStart+0x21


其他有用的遍历指令包括:


§  ~*r

显示线程寄存器信息。

0:003> ~*r
rax=0000000000000214 rbx=0000000000000002 rcx=0000000000000002
rdx=0000000000d3f8a8 rsi=0000000000000000 rdi=0000000000000002
rip=00007ffe71395ef4 rsp=0000000000d3f528 rbp=0000000000000000
 r8=0000000000000001  r9=00000000ffffffff r10=0000000000000000
r11=0000000000000244 r12=00000000ffffffff r13=0000000000d3f8a8
r14=0000000000000000 r15=0000000000000001
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwWaitForMultipleObjects+0x14:
00007ffe`71395ef4 c3              ret
rax=000000000307f790 rbx=0000000002db4e50 rcx=000000000307f7a4
rdx=0000000000000110 rsi=0000000000000010 rdi=0000000002db51d0
rip=00007ffe71398c34 rsp=000000000307fc18 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=000000000307f790 r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
rax=0000000070fa5000 rbx=0000000002db5c00 rcx=0000000000000042
rdx=0000000000536e7b rsi=0000000000000010 rdi=0000000002db5f80
rip=00007ffe71398c34 rsp=000000000317f828 rbp=0000000000000000
 r8=000000000000058c  r9=00000000000015db r10=0000000000000000
r11=0000000070fa4fee r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
rax=000000000000002d rbx=0000000002db8d20 rcx=000000000327ea50
rdx=00007ffe6d41e9e8 rsi=0000000000000010 rdi=0000000002db90a0
rip=00007ffe71398c34 rsp=000000000327f508 rbp=0000000000000000
 r8=0000000000000010  r9=000000000000001e r10=00007ffe71449d80
r11=0000000000000000 r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
rax=0000000000000000 rbx=0000000000000000 rcx=00007ff7160e23b0
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=00007ff7160d171b rsp=00000000052bfd20 rbp=0000000000000000
 r8=00000000052bfc78  r9=0000000000000000 r10=0000000000000000
r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010204
ttt!ReadRoutine+0xab:
00007ff7`160d171b 8b10            mov     edx,dword ptr [rax] ds:00000000`00000000=????????
rax=0000000004b93810 rbx=0000000000000000 rcx=00000000053bf930
rdx=0000000004b93c10 rsi=0000000000000000 rdi=0000000000000000
rip=00007ff7160d359e rsp=00000000053bf800 rbp=0000000000000000
 r8=00007ff7160e23b0  r9=0000000000000003 r10=00007ffe714095d0
r11=0000000000000001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
ttt!std::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>+0xe:
00007ff7`160d359e e852dbffff      call    ttt!ILT+240(??0?$_Iterator_with_baseUrandom_access_iterator_tagstdPEAH_JPEBQEAHAEBQEAHV_Iterator_base (00007ff7`160d10f5)


§  ~*e  k;r

此命令意为:在所用线程环境中(~*),分别执行(e)栈指令(k)和寄存器指令(r)。



0:003> ~*e  k;r
Child-SP          RetAddr           Call Site
00000000`00d3f528 00007ffe`6e37dcb0 ntdll!ZwWaitForMultipleObjects+0x14
00000000`00d3f530 00007ffe`6e37dbae KERNELBASE!WaitForMultipleObjectsEx+0xf0
00000000`00d3f830 00007ff7`160d164c KERNELBASE!WaitForMultipleObjects+0xe
00000000`00d3f870 00007ff7`160d65e1 ttt!main+0x11c [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 49]
00000000`00d3f8f0 00007ff7`160d5de2 ttt!WinMain+0xb1 [c:\qt\4.8.4\src\winmain\qtmain_win.cpp @ 131]
00000000`00d3f960 00007ff7`160d5ade ttt!__tmainCRTStartup+0x2f2 [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 578]
00000000`00d3fa50 00007ffe`6f2b2774 ttt!WinMainCRTStartup+0xe [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 403]
00000000`00d3fa80 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`00d3fab0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=0000000000000214 rbx=0000000000000002 rcx=0000000000000002
rdx=0000000000d3f8a8 rsi=0000000000000000 rdi=0000000000000002
rip=00007ffe71395ef4 rsp=0000000000d3f528 rbp=0000000000000000
 r8=0000000000000001  r9=00000000ffffffff r10=0000000000000000
r11=0000000000000244 r12=00000000ffffffff r13=0000000000d3f8a8
r14=0000000000000000 r15=0000000000000001
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwWaitForMultipleObjects+0x14:
00007ffe`71395ef4 c3              ret
Child-SP          RetAddr           Call Site
00000000`0307fc18 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0307fc20 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0307ff30 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0307ff60 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=000000000307f790 rbx=0000000002db4e50 rcx=000000000307f7a4
rdx=0000000000000110 rsi=0000000000000010 rdi=0000000002db51d0
rip=00007ffe71398c34 rsp=000000000307fc18 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=000000000307f790 r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
Child-SP          RetAddr           Call Site
00000000`0317f828 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0317f830 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0317fb40 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0317fb70 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=0000000070fa5000 rbx=0000000002db5c00 rcx=0000000000000042
rdx=0000000000536e7b rsi=0000000000000010 rdi=0000000002db5f80
rip=00007ffe71398c34 rsp=000000000317f828 rbp=0000000000000000
 r8=000000000000058c  r9=00000000000015db r10=0000000000000000
r11=0000000070fa4fee r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
Child-SP          RetAddr           Call Site
00000000`0327f508 00007ffe`71331553 ntdll!ZwWaitForWorkViaWorkerFactory+0x14
00000000`0327f510 00007ffe`6f2b2774 ntdll!TppWorkerThread+0x293
00000000`0327f820 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`0327f850 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=000000000000002d rbx=0000000002db8d20 rcx=000000000327ea50
rdx=00007ffe6d41e9e8 rsi=0000000000000010 rdi=0000000002db90a0
rip=00007ffe71398c34 rsp=000000000327f508 rbp=0000000000000000
 r8=0000000000000010  r9=000000000000001e r10=00007ffe71449d80
r11=0000000000000000 r12=0000000000000000 r13=0000000002db31c0
r14=00007ffe71332a50 r15=00007ffe71332ef0
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!ZwWaitForWorkViaWorkerFactory+0x14:
00007ffe`71398c34 c3              ret
Child-SP          RetAddr           Call Site
00000000`052bfd20 00007ffe`6f2b2774 ttt!ReadRoutine+0xab [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 20]
00000000`052bfdc0 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`052bfdf0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=0000000000000000 rbx=0000000000000000 rcx=00007ff7160e23b0
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=00007ff7160d171b rsp=00000000052bfd20 rbp=0000000000000000
 r8=00000000052bfc78  r9=0000000000000000 r10=0000000000000000
r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010204
ttt!ReadRoutine+0xab:
00007ff7`160d171b 8b10            mov     edx,dword ptr [rax] ds:00000000`00000000=????????
Child-SP          RetAddr           Call Site
00000000`053bf800 00007ff7`160d3126 ttt!std::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>+0xe
00000000`053bf830 00007ff7`160d23e7 ttt!std::_Vector_const_iterator<int * __ptr64,std::allocator<int * __ptr64> >::_Vector_const_iterator<int * __ptr64,std::allocator<int * __ptr64> >+0x26 [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 68]
00000000`053bf880 00007ff7`160d1aee ttt!std::_Vector_iterator<int * __ptr64,std::allocator<int * __ptr64> >::_Vector_iterator<int * __ptr64,std::allocator<int * __ptr64> >+0x27 [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 322]
00000000`053bf8b0 00007ff7`160d1788 ttt!std::vector<int * __ptr64,std::allocator<int * __ptr64> >::end+0x2e [c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector @ 651]
00000000`053bf8f0 00007ffe`6f2b2774 ttt!WriteRoutine+0x38 [c:\users\winne\documents\visual studio 2008\projects\ttt\ttt\main.cpp @ 28]
00000000`053bf980 00007ffe`71360d51 kernel32!BaseThreadInitThunk+0x14
00000000`053bf9b0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
rax=0000000004b93810 rbx=0000000000000000 rcx=00000000053bf930
rdx=0000000004b93c10 rsi=0000000000000000 rdi=0000000000000000
rip=00007ff7160d359e rsp=00000000053bf800 rbp=0000000000000000
 r8=00007ff7160e23b0  r9=0000000000000003 r10=00007ffe714095d0
r11=0000000000000001 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
ttt!std::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>::_Ranit<int * __ptr64,__int64,int * __ptr64 const * __ptr64,int * __ptr64 const & __ptr64>+0xe:
00007ff7`160d359e e852dbffff      call    ttt!ILT+240(??0?$_Iterator_with_baseUrandom_access_iterator_tagstdPEAH_JPEBQEAHAEBQEAHV_Iterator_base (00007ff7`160d10f5)

线程时间


在软件调试的时候,若发现某线程占用执行时间过多,就需要当心是否有问题。线程执行时间的多少,其实就是占用CPU执行工作的时间多少。某线程占用越多,此长彼消,则系统中其它线程占用CPU的时间就越少。

线程的时间信息包括三个方面:自创建之初到现在的总消耗时间、用户模式执行时间、内核模式执行时间。需注意的是,消耗时间一定会远远大于用户时间+内核时间,多出来的是大量空闲时间(为Idle进程占用)。使用下面的命令查看线程时间:

§  .ttime

§  !runaway 7

在!runaway命令中加入标志值7,将显示线程的全部三种时间值。

这两个命令的区别之处是,.ttime只能显示当前线程的时间信息,!runaway能显示当前进程的所有线程时间。下图是这两个命令的使用情况:


0:003> .ttime
Created: Thu Dec 28 16:09:31.131 2017 (UTC + 8:00)
Kernel:  0 days 0:00:00.000
User:    0 days 0:00:00.000


0:003>  !runaway 7
 User Mode Time
  Thread       Time
   5:1674      0 days 0:00:00.015
   4:bf78      0 days 0:00:00.000
   3:85ec      0 days 0:00:00.000
   2:84f0      0 days 0:00:00.000
   1:7274      0 days 0:00:00.000
   0:2edc      0 days 0:00:00.000
 Kernel Mode Time
  Thread       Time
   0:2edc      0 days 0:00:00.015
   5:1674      0 days 0:00:00.000
   4:bf78      0 days 0:00:00.000
   3:85ec      0 days 0:00:00.000
   2:84f0      0 days 0:00:00.000
   1:7274      0 days 0:00:00.000
 Elapsed Time
  Thread       Time
   0:2edc      0 days 0:00:20.875
   1:7274      0 days 0:00:20.868
   2:84f0      0 days 0:00:20.868
   3:85ec      0 days 0:00:20.868
   4:bf78      0 days 0:00:00.037
   5:1674      0 days 0:00:00.037



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值