.NET / Rotor原始碼分析4 - 修改Rotor使其傳送CLR Notification
在使用WinDbg + SOS正式跟蹤Rotor的原始碼研究.NET的實現之前,還有個問題需要解決:Rotor預設並不會發出CLR Notification。CLR Notification是指CLR在執行的時候發出的一些通知,比如載入模組,程式碼被編譯等等,這些通知對於除錯Rotor / .NET以及SOS都非常重要。例如你可以設定偵錯程式為一遇到CLR Notification便中斷,在某些情況下非常有用。還有就是SOS的部分命令如BPMD等依賴於CLR notification實現其部分功能。因此這個問題必須得解決。
CLR Notifcation本質上其實就是一個SEH (Structured Exception Handling)異常。同時VC的異常以及CLR本身的託管異常也是SEH異常,只是他們的Exception Code不同和引數不同而已。CLR通過呼叫RaiseException函式產生Exception Code = CLR Notification的異常,這個異常並不會導致程式非正常退出,而是僅僅對偵錯程式起到一個通知作用,CLR本身在異常處理程式碼中會自動處理掉這個異常。
Rotor通過間接呼叫DACNotificationHelper來產生CLR Notification,如下:
void DACNotifyExceptionHelper(TADDR *args,UINT argCount) { PAL_TRY { if (IsDebuggerPresent() && !CORDebuggerAttached()) { RaiseException(CLRDATA_NOTIFY_EXCEPTION, 0, argCount, (ULONG_PTR *) args); } } PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { } PAL_ENDTRY } |
可以看到Rotor呼叫RaiseException產生程式碼為CLRDATA_NOTIFICATION_EXCEPTION的SEH異常,也就是CLR Notification,這個異常將被後面的PAL_EXCEPT塊(類似__except)處理,不作任何事情,直接“吞掉”異常。啟動偵錯程式跟蹤一下發現在if語句時候並沒有對IsDebuggerPresent() API進行呼叫,這個函式的作用是檢查程式是否被正在被偵錯程式所除錯,只有在偵錯程式掛接上此程式並且CLR偵錯程式沒有掛接上的時候才會發生此種Notification。進一步觀察彙編:
xor eax, eax test eax,eax je mscorwks!DACNotifyExceptionHelper+0x89 |
發現這裡沒有呼叫API而直接對eax賦值為0,然後加以判斷,提示IsDebuggerPresent可能被定義成FALSE。在命令列下面輸入:
D:/usr/src/sscli20>findstr /s "IsDebuggerPresent" *.c *.cpp *.h binaries.x86dbg.rotor/sdk/pal/inc/rotor_palrt.h:#define IsDebuggerPresent() FALSE
clr/src/debug/ee/debugger.cpp: if (IsDebuggerPresent() && !g_pRCThread->G etDCB(iWhich)->m_rightSideIsWin32Debugger) clr/src/utilcode/debug.cpp: t_pDbgPres pFcn = (t_pDbgPres) GetProcAdd ress(hKrnl32, "IsDebuggerPresent"); clr/src/vm/eeconfig.h: if (IsDebuggerPresent()) DebugBreak(); / clr/src/vm/i386/gmsx86.cpp: if (IsDebuggerPresent()) clr/src/vm/pefile.cpp: BOOL fOutputToDebugger = (level == LL_ERROR && IsDebug gerPresent()); clr/src/vm/stubmgr.cpp: if (IsDebuggerPresent()) clr/src/vm/util.cpp: if (IsDebuggerPresent() && !CORDebuggerAttached()) palrt/inc/rotor_palrt.h:#define IsDebuggerPresent() FALSE |
發現果然IsDebuggerPresent被定義為FALSE,看來是Rotor將其禁止掉了。因為我們這裡目的是對.NET / Rotor進行研究,不太在意程式的效能,因此這裡只需要將這裡的IsDebuggerPresent定義成TRUE重新編譯即可。
修改之後重新編譯,啟動Windbg除錯clix,執行一個託管程式碼程式,可以在偵錯程式中發現類似下面的輸出:
(1464.c88): CLR notification exception - code e0444143 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. |
可以看到CLR Notification已經被Windbg接收到了,之後,如果想當每一個CLR Notifcation到來的時候讓偵錯程式中斷,只需輸入:
sxe clrn |
Clrn代表CLR Notification所對應的Exception Code,預定義在WinDbg內部。
OK,至此我們的準備工作完成,下一篇文章我們將正式使用WinDbg+SOS來除錯一個託管程式在CLR中的執行過程。
作者: 張羿/ATField
Blog: http://blog.csdn.net/atfield
轉載請註明出處
相關文章
- .NET / Rotor原始碼研究3 – 除錯Rotor託管程式碼的利器:WinDbg和SOS原始碼除錯
- .NET / Rotor原始碼分析5 - 開始使用WinDbg+SOS除錯,sscoree.dll,載入SOS並設定JIT斷點原始碼除錯斷點
- Rotor實現中用到的Macro(摘自Shared Source CLI Essentials)Mac
- Ant design的Notification原始碼分析原始碼
- Android系統原始碼分析-Broadcast傳送Android原始碼AST
- MPTCP 原始碼分析(四) 傳送和接收資料TCP原始碼
- Netty4.x原始碼分析Netty原始碼
- laravel 傳送郵件修改密碼Laravel密碼
- 郵件傳送庫原始碼原始碼
- Microsoft 釋出Rotor,一場Shared Source對Open Source的速度比賽 (轉)ROS
- Android8.1 SystemUI原始碼分析之 Notification流程AndroidSystemUI原始碼
- [原始碼分析] 分散式任務佇列 Celery 之 傳送Task & AMQP原始碼分散式佇列MQ
- .net原始碼分析 – List原始碼
- .net core 原始碼分析原始碼
- Laravel 重置密碼傳送郵件分析Laravel密碼
- 【Netty】(4)—原始碼AbstractBootstrapNetty原始碼boot
- antd原始碼解讀(10)- notification原始碼
- twitter storm原始碼走讀之2 -- tuple訊息傳送場景分析ORM原始碼
- webpack4原始碼分析Web原始碼
- Android 特殊使用者通知用法彙總 - Notification 原始碼分析Android原始碼
- Net6 DI原始碼分析Part4 CallSiteFactory ServiceCallSite原始碼
- Netty Channel原始碼分析Netty原始碼
- Netty原始碼分析----PoolChunkNetty原始碼
- netty : NioEventLoopGroup 原始碼分析NettyOOP原始碼
- AFNetworking原始碼分析原始碼
- CBNetworking:原始碼分析原始碼
- C# 傳送電子郵件原始碼片段C#原始碼
- 從原始碼看 ObjC 中訊息的傳送原始碼OBJ
- 【Redis】修改redis-trib.rb使其import支援密碼RedisImport密碼
- 直播平臺原始碼,簡訊驗證碼傳送demo原始碼
- k8s client-go原始碼分析 informer原始碼分析(4)-DeltaFIFO原始碼分析K8SclientGo原始碼ORM
- Architecture(4)LitePal原始碼分析原始碼
- EOS原始碼分析(4)錢包原始碼
- Netty原始碼分析-- FastThreadLocal分析(十)Netty原始碼ASTthread
- Netty 原始碼分析-目錄Netty原始碼
- Netty原始碼分析(四):EventLoopGroupNetty原始碼OOP
- Netty原始碼分析(五):EventLoopNetty原始碼OOP
- Netty原始碼分析--NIO(一)Netty原始碼