windbg 邊學邊記attach 進程和open dump的兩個方式查看線程的占用cpu資源


首先我是attach到進程的方式,附加到進程把. vs里邊有個遠程調試就是通過連接到遠程機附加到進程操作的.在 有公網IP情況下挺好用,但涉及到nat穿越之類的,因為用戶的不方便設置,這種調試方式也有局限性.

 

 

6、 lmf

列出當前進程中加載的所有dll文件和對應的路徑

奇怪沒找到我程序里邊加載的dll  乖乖滴.難道attach 進程把dll關了嗎? 用空用dump 試試.

11!runaway 可以顯示每一個線程的cpu消耗 

這個命令挺好,直接找到哪個線程占得時間久 ,如果一直占着,那這個線程里邊一定是有死循環,或者不停的操作某個東西

線程6號 占用時間1分鍾31秒

我看有人通過抓dump  才查看,那種應該是最准的吧, windbg  附加到進程里之后,程序卡掉了,占資源的dll 也停下來了.    總結下文的操作,發現加載到進程跟dump 的方式竟然一樣,不一樣的估計是加載到進程里增大資源影響程序的運行效果的公正性吧.但差距不大吧.

通過dump多抓幾次,每次都一樣占時間的那個線程就是問題所在的線程.

12、 ~     命令是用來切換目標線程

0:018> ~ 可以顯示線程的信息
0:018> ~0s   把當前的線程切換到0號線程,也就是主線程,切換后提示符會變為0:000.

13 、~* 命令列出當前進程中的所有線程的詳細信息

14、~*kb    命令列出所有線程的堆棧

15、 k     命令用來顯示當前線程的堆棧,如下

 

轉到六號線程 

 

沒有多少信息 這是0:007> !clrstack轉到這個線程  沒有列出線程的占用資源情況

應該繼續下邊的命令

!clrstack 
15、 k     命令用來顯示當前線程的堆棧,如下

0:018> k
跟d命令一樣,k后面也可以跟很多后綴,比如kb kp,kn,kv,kl等,這些后綴控制了顯示的格式和信息。
棧指令k[b|p|P|v]
這四條指令顯示的內容類似,但是每個指令都有特色;

KB顯示三個參數;

Kp顯示所有的參數,但需要Full Symbols或Private PDBSymbols支持。KP與Kp相似,只是KP將參數換行顯示了;

Kv用於顯示FPO和調用約定;

KD,用於顯示Stack的Dump,在跟蹤棧時比較有用。
這些指令區分大小。

16 、u   命令把指定地址上的代碼翻譯成匯編輸出

0:018> u 7739d023 
USER32!NtUserWaitMessage:
7739d023 b84a120000 mov eax,0x124a
7739d028 ba0003fe7f mov edx,0x7ffe0300
7739d02d ff12 call dword ptr [edx]
7739d02f c3 ret
如果符號文件加載正確,可以用uf命令直接反匯編整個函數,比如uf USER32! NtUserWaitMessage

 

通過抓dump的方式

0:000> !runaway
User Mode Time
Thread Time
7:1dec 0 days 0:00:37.578
0:1278 0 days 0:00:00.078
8:1274 0 days 0:00:00.015
6:2248 0 days 0:00:00.015
17:1378 0 days 0:00:00.000
16:1ff0 0 days 0:00:00.000
15:3a4 0 days 0:00:00.000
14:1e88 0 days 0:00:00.000
13:1dc4 0 days 0:00:00.000
12:ec4 0 days 0:00:00.000
11:1b98 0 days 0:00:00.000
10:2074 0 days 0:00:00.000
9:9f4 0 days 0:00:00.000
5:154c 0 days 0:00:00.000
4:1bd4 0 days 0:00:00.000
3:8ac 0 days 0:00:00.000
2:48c 0 days 0:00:00.000
1:75c 0 days 0:00:00.000

0:000> ~7s
ntdll!NtWaitForSingleObject+0xa:
00007ffd`284f386a c3 ret

 調整到7號線程上下文 

0:007> !clrstack
No export clrstack found

看來我是.net 環境沒load 正確的sos 吧

想通過加載sos.dll 出現下邊錯誤 . 

0:007> .load C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll
The call to LoadLibrary(C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll) failed, Win32 error 0n193
"%1 不是有效的 Win32 應用程序。"
Please check your debugger configuration and/or network access.

 

  問題一:WinDBG分X86和X64兩個版本

  如果你用的是32位的WinDBG,那直接打開就行;你如果用的是64位的版本,那么如果調試64位代碼也直接打開,如果調試x86的代碼,要使用Wow64下的WinDBG.exe。

  問題二:確定SOS和CLR的位置和版本

  如果安裝了Visual Studio的機器,可以打開VS的命令行,輸入where sos.dll命令,可以找到sos.dll的全路徑(需要說明的是,找到的不一定是全部的文件)。它的一般位置在C:\Windows\Microsoft.NET\Framework?\version?\SOS.dll。其中Framework?包括Framework和Framework64兩個版本;version?包括v2.0.50727,v3.0,v3.5和v4.0.30319等版本。文件確切路徑的選擇依據要調試程序的版本而定,一般為C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll,CLR為同一目錄下的CLR.dll文件。

  問題三:加載SOS和CLR

  運氣好的話,使用命令.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll可以加載成功。如果失敗,特別是出現The call to LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll) failed, Win32 error 0n193這樣的錯誤,請確認加載sos.dll的版本是否正確。

  此外,加載不出錯,並不見得可以直接使用。可以嘗試命令.loadby sos clr。如果命令成功,那么測試環境好了。如果出現了“Unable to find module 'clr'”這樣的錯誤。請鍵入g讓調試程序運行一會兒,停下來的時候再嘗試命令.loadby sos clr,這時一般都會成功。

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>where sos.dll
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll

0:007> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll

什么提示也沒有,看來是正確了嗎

繼續上邊的

0:007> ~7s
ntdll!NtWaitForSingleObject+0xa:
00007ffd`284f386a c3 ret

終於成功:

0:007> !clrstack
OS Thread Id: 0x1dec (7)
        Child SP               IP Call Site
000000001d05f1c8 00007ffd284f386a [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
000000001d05f1c8 00007ffca7bb59dc [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
000000001d05f1a0 00007ffca7bb59dc DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, UInt32)
000000001d05f250 00007ffca7bb5909 Cognex.DataMan.LegacyUtils.PInvoke.WaitOne(IntPtr, UInt32)
000000001d05f280 00007ffca7bb580c Cognex.DataMan.LegacyUtils.BlockingCollection`1[[System.__Canon, mscorlib]].DequeueWithCancellation(Cognex.DataMan.LegacyUtils.CancellationToken)
000000001d05f2d0 00007ffca7bb5544 Cognex.DataMan.CogNamer.CogNamerListener.CogNamerDispatcherThreadFunc(System.Object)
000000001d05f320 00007ffcfcacaffe System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000001d05f3f0 00007ffcfcacae97 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000001d05f420 00007ffcfcacae52 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
000000001d05f470 00007ffcfca1c142 System.Threading.ThreadHelper.ThreadStart()
000000001d05f6c8 00007ffd07213cd3 [GCFrame: 000000001d05f6c8] 
000000001d05fa18 00007ffd07213cd3 [DebuggerU2MCatchHandlerFrame: 000000001d05fa18] 

接觸了幾天了,今天終於是操作了一個流程下來,能看到這個線程的托管代碼了

 

000000001d05f1c8 00007ffd284f386a [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
000000001d05f1c8 00007ffca7bb59dc [InlinedCallFrame: 000000001d05f1c8] Cognex.DataMan.LegacyUtils.PInvoke.WaitForSingleObject(IntPtr, UInt32)
000000001d05f1a0 00007ffca7bb59dc DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, UInt32)

也列出了其中占資源大的托管代碼

 

參考

http://www.360doc.com/content/12/0524/13/8053702_213354653.shtml

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM