2010年10月17日 星期日

使用WindDBG附加程序除錯Silverlight應用程式

 

使用的程式碼如下:

  1: private void MyButton_Click(object sender, RoutedEventArgs e)
  2: {
  3:     try
  4:     {
  5: 	    throw new Exception("Test exception");
  6:     }
  7:     catch
  8:     {
  9:     }
 10:     Thread.Sleep(25000);
 11:     MyButton.Content = "Pushed";
 12: } 

1. 首先要知道正在執行的應用程式ProcessID,這邊我使用Process Explorer這一套軟體來抓。


image


image 


2. 進入WinDBG,打開[File]->[Attach to a Process…],選取剛剛找到的ProcessID。


image


3. 載入正確的WinDBG Extension DLL – SOS.dll,讓我們可以看到.NET Framework的Managed 程式碼。


(據測試的結果,本步驟可省略,但用!eeversion.chain確認一下較好)


可以用Everything來看一下有哪些SOS.dll


image


看一下目前的執行期環境,我們要挑一個和目前執行期環境相同版本的SOS.dll。


0:022> lm v m *clr*  <== List Loaded Modules(v = verbose;m Pattern )
start    end        module name
63450000 637b9000   coreclr    (deferred)            
    Image path: c:\Program Files\Microsoft Silverlight\4.0.50917.0\coreclr.dll
    Image name: coreclr.dll
    Timestamp:        Fri Sep 17 12:06:19 2010 (4C92E93B)
    CheckSum:         00361079
    ImageSize:        00369000
    File version:     4.0.50917.0
    Product version:  4.0.50917.0
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® Silverlight
    InternalName:     coreclr.dll
    OriginalFilename: coreclr.dll
    ProductVersion:   4.0.50917.0
    FileVersion:      4.0.50917.0 (SL_V4_SVC.050917-0000)
    FileDescription:  Microsoft .NET Runtime Common Language Runtime - WorkStation
    LegalCopyright:   © Microsoft Corporation.  All rights reserved.
    Comments:         Flavor=Retail


也可以使用!eeversion指令。


0:028> !eeversion ==> (顯示 Common Language Runtime 版本)
4.0.50917.0 retail
Workstation mode
SOS Version: 4.0.50917.0 retail build


0:011> .reload ==> (Reload Module)
Reloading current modules
................................................................
............................................................
0:011> .load C:\Program Files\Microsoft Silverlight\4.0.50917.0\sos.dll ==>(Load Extension DLL)


檢查Extension DLL是否已經正確載入


0:011> .chain ==>(List Debugger Extensions)
Extension DLL search Path:
    C:\Program Files\Debugging Tools for Windows (x86)\WINXP;C:\Program Files\Debugging Tools for Windows (x86)\winext;C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\Debugging Tools for Windows (x86)\pri;C:\Program Files\Debugging Tools for Windows (x86);C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade(...省略)
Extension DLL chain:
    C:\Program Files\Microsoft Silverlight\4.0.50917.0\sos: image 4.0.50917.0, API 1.0.0, built Fri Sep 17 12:08:16 2010
        [path: C:\Program Files\Microsoft Silverlight\4.0.50917.0\sos.dll]
    C:\Program Files\Microsoft Silverlight\4.0.50917.0\sos.dll: image 4.0.50917.0, API 1.0.0, built Fri Sep 17 12:08:16 2010
        [path: C:\Program Files\Microsoft Silverlight\4.0.50917.0\sos.dll]
    dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 04:08:26 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\dbghelp.dll]
    ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:31 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\ext.dll]
    exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:24 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\exts.dll]
    uext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:23 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\winext\uext.dll]
    ntsdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 04:08:08 2010
        [path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\ntsdexts.dll]


4. 列出Internet Explorer裡面的執行序,找出應用程式使用的ThreadID和他的內容。


0:011> ~* e !clrstack ==>(~ = 執行序; * = 全部; e = 執行; !clrstack = 提供 Managed 程式碼的堆疊追蹤)
OS Thread Id: 0x7ac (0)
Unable to walk the managed stack. The current thread is likely not a
managed thread. You can run !threads to get a list of managed threads in
the process
(...省略)
OS Thread Id: 0x163c (4)
Child SP IP       Call Site
020ed848 77b164f4 [HelperMethodFrame: 020ed848] System.Threading.Thread.SleepInternal(Int32)
020ed888 62a68e05 System.Threading.Thread.Sleep(Int32)
020ed88c 041e042d
SilverlightApplication1.MainPage.MyButton_Click(System.Object, System.Windows.RoutedEventArgs)
020ed8c4 632a0b81 System.Windows.Controls.Primitives.ButtonBase.OnClick()
020ed8d8 632f9d24 System.Windows.Controls.Button.OnClick()
020ed8e4 632a058e System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs)
020ed8f4 63262e01 System.Windows.Controls.Control.OnMouseLeftButtonUp(System.Windows.Controls.Control, System.EventArgs)
020ed904 63260f44 MS.Internal.JoltHelper.FireEvent(IntPtr, IntPtr, Int32, Int32, System.String)
020ed948 632e702f DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int32, Int32, Int32, Int32, IntPtr)
020eda24 071c6dbc [ContextTransitionFrame: 020eda24]
OS Thread Id: 0xe10 (5)
Unable to walk the managed stack. The current thread is likely not a
managed thread. You can run !threads to get a list of managed threads in
the process
(...省略)


5. 列出Exception的記憶體回收堆積 (Heap) 資訊,取得最近的Method Table物件(這裡是指Exception物件)。


0:011> !dumpheap -type Exception ==>(列出記憶體回收堆積; –type 只會列出相同型別與子型別的物件)
Address       MT     Size
078e1024 62c52b94       80    
078e1074 62c5b580       80    
078e10c4 62c5b5c8       80    
078e1114 62c5b658       80    
078e1164 62c5da48       80    
078e11b4 62c5da48       80    
078e4c24 62c33358       32    
078eb200 633533ac       32    
078eb220 633782a0       32    
078fac6c 6334a330       32    
0791f8b4 62c52b94       80    
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
633782a0        1           32 MS.Internal.Error+GetExceptionTextDelegate
633533ac        1           32 MS.Internal.Error+ClearExceptionDelegate
6334a330        1           32 System.EventHandler`1[[System.Windows.ApplicationUnhandledExceptionEventArgs, System.Windows]]
62c33358        1           32 System.UnhandledExceptionEventHandler
62c5b658        1           80 System.ExecutionEngineException
62c5b5c8        1           80 System.StackOverflowException
62c5b580        1           80 System.OutOfMemoryException
62c5da48        2          160 System.Threading.ThreadAbortException
62c52b94        2          160 System.Exception
Total 11 objects


6. 列出參考到這個Method Table物件(這裡是指Exception物件)的位址


0:011> !dumpheap -mt 62c52b94 ==> (列出記憶體回收堆積; –mt 列出對應到 MethodTable 結構之物件)       
Address       MT     Size
078e1024 62c52b94       80    
0791f8b4 62c52b94       80    
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
62c52b94        2          160 System.Exception
Total 2 objects


7. 列出物件內容,這邊是Exception,所以使用!pe指令。


0:011> !pe 0791f8b4 ==>(print exception)
Exception object: 0791f8b4
Exception type:   System.Exception
Message:          Test exception
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    020ED88C 041E0417 UNKNOWN!SilverlightApplication1.MainPage.MyButton_Click(System.Object, System.Windows.RoutedEventArgs)+0x57


StackTraceString: <none>
HResult: 80131500
The current thread is unmanaged


結論:


這個例子體現了尋找錯誤必須要由大往小,由粗往細的過程。


由Process到Thread: ProcessID => ~* e !clrstack


由物件到函式表:!dumpheap –type xxx => !dumpheap –mt xxx


參考資料:


沒有留言:

張貼留言