A. 如何在Visual Studio 2005中對Managed 程式碼及非託管的CLR環境同時進行調試?
步驟遠比你想象的簡單,而且更重要的是比windbg方便。舉例:
| 1. |
開啟一個C#的項目,開啟該項目的屬性視窗 |
| 2. |
將Debug頁面中的Enable Unmanaged Code Debugging選中 |
| 3. |
在某語句處設定好斷點,F5重新編譯,運行,命中斷點 |
| 4. |
開啟Immediate視窗,輸入!Load sos.dll載入CLR調試擴充(這個sos.dll是.NET Framework 2.0 SDK內建的) |
| 5. |
然後在Immediate視窗裡開始愉快的!DumpStackObjects、!DumpClass、!DumpMT,一窺CLR內部堂奧吧。!Help是協助 |
| 6. |
使用這種方式,對於Managed 程式碼的調試跟平時並沒有啥區別 |
B. 可以使用Visual Studio 2005來調試Rotor 2.0編譯的Managed 程式碼嗎?
不行。Rotor對Managed 程式碼調試支援不全,只能使用其內建的cordbg來進行調試(無意中發現Rotor內建的cordbg版本號碼居然比SDK 2.0的還要高,一個是2.0.50826,一個是2.0.50727 RTM....-_-b)
C. 可以使用Visual Studio 2005來跟蹤和調試非託管的Rotor代碼嗎?
雖然不能直接用vs2005來調試Rotor編譯的Managed 程式碼,但是,調試Rotor本身卻是可以的!步驟也不是很複雜:
| 1. |
用記事本編輯Rotor編譯所得的sos.dll.manifest檔案(例如d:\Rotor2\binaries.x86chk.Rotor\sos.dll.manifest) |
2. |
copy其中<dependency>...</dependency>部分內容,將其paste進C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe.manifest檔案的<assembly>一節當中,儲存之 |
| 3. |
假設某Rotor2下編譯的託管測試檔案的全路徑名為d:\Rotor2\samples\hello.exe |
| 4. |
Rotor控制台下輸入"devenv /debugexe clix d:\Rotor2\samples\hello.exe",啟動vs2005,載入clix |
| 5. |
F5啟動,稍等幾秒鐘,確信Rotor的運行時環境已啟動,然後按Ctrl-Alt-Break搶佔中斷clix執行 |
| 6. |
開啟Immediate視窗,輸入!Load d:\Rotor2\binaries.x86chk.Rotor\sos.dll,載入Rotor自己編譯產生的CLR調試擴充 |
| 7. |
好戲開始了!快單步跟蹤、輸入>cmd / !threads / !dumpstack試試看吧! |
D. "稍等幾秒鐘,確信Rotor的運行時環境已啟動,再按Ctrl-Alt-Break搶佔中斷其執行"是啥意思?
意思就是說,在調試Rotor時,如何合理、適時地設定斷點是關鍵。為了簡單起見,可以在上述那個簡單樣本中使用一條Console.ReadLine語句暫時鎖死流程的執行,啟動後稍等一會兒再按Ctrl-Alt-Break返回調試器,這樣我們便能保證中斷時Rotor的運行時環境已經完成載入了。
或者更專業一點,還可以通過設定環境變數來啟動Rotor的輔助調試機制,如COMPlus_BreakOnEELoad、COMPlus_JitBreak等,這比“猜測式斷點”更準確、更方便,這裡就不多說了,請進一步參考Rotor內建的調試文檔,裡面說得很詳細。
參考文獻:
[1] Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects, MSDN Magazine, May 2005
[2] SOS: It's Not Just an ABBA Song Anymore, MSDN Magazine, MSDN Magazine, Jun. 2003
[3] SOS Debugging with the CLR, Jason Zander's Blog, Oct. 2003