日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WinDbg+Rotor解析WinForm调用堆栈及实现

發布時間:2025/3/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WinDbg+Rotor解析WinForm调用堆栈及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前段寫過一篇文章“CLR探索系列:深入追蹤托管exe加載執行過程”,在那篇文章中,主要是側重靜態代碼的分析,追蹤源代碼的流程一步一步看是如何實現的。

這次,寫一篇文章,結合Windbg,從一個托管應用程序執行的調用堆棧開始,追蹤其調用堆棧中的線索,以及這些托管應用程序執行中調用的功能實現,來展示托管代碼的加載和執行的流程和實現。

首先還是找一個小白鼠:

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

?

?????public partial class Form1 : Form

??? {

??????? public Form1()

??????? {

??????????? InitializeComponent();

??????? }

??????? private void button1_Click(object sender, EventArgs e)

??????? {

??????????? System.Object o = new object();

??????????? lock (o)

??????????? {

??????????????? System.GC.Collect();

??????????? }

???????? }

}

?

這里找的是一個WinForm應用程序來作為小白鼠。

咱就不采用在調用的關鍵的mscorwksMscoeEE的方法上面下斷點來跟蹤,然后解釋每個斷點調用堆棧和環境的解釋方法了,直接把main threadcall stack給打出來一行一行的去挖掘好了。

?

打開Windbg,附加到進程,加載好相關的symbol2.0SOS,切換到第0Thread然后輸出其調用堆棧:

?

0:000> k

ChildEBP RetAddr?

0012f4a0 7c92e9ab ntdll!KiFastSystemCallRet

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0012f3c4 7b08432d USER32!NtUserWaitMessage+0xc

0012f434 7b08416b System_Windows_Forms_ni+0xb432d

0012f464 7b0c69fe System_Windows_Forms_ni+0xb416b

0012f490 79e88ee4 System_Windows_Forms_ni+0xf69fe

0012f510 79e88e31 mscorwks!CallDescrWorkerWithHandler+0xa3

0012f650 79e88d19 mscorwks!MethodDesc::CallDescr+0x19c

0012f668 79e88cf6 mscorwks!MethodDesc::CallTargetWorker+0x20

0012f67c 79f084b0 mscorwks!MethodDescCallSite::Call+0x18

0012f7e0 79f082a9 mscorwks!ClassLoader::RunMain+0x220

0012fa48 79f0817e mscorwks!Assembly::ExecuteMainMethod+0xa6

0012ff18 79f07dc7 mscorwks!SystemDomain::ExecuteMainMethod+0x398

0012ff68 79f05f61 mscorwks!ExecuteEXE+0x59

0012ffb0 79011b5fmscorwks!_CorExeMain+0x11b

0012ffc0 7c816fd7 mscoree!_CorExeMain+0x2c

0012fff0 00000000 KERNEL32!BaseProcessStart+0x23

?

BaseProcessStart表示的是運行的Winform啟動的進程。在前面的上一篇文章里面已經分析過,并且用相關的工具查看過,一個托管模塊開始運行的時候只想的是_CorExeMain方法。這是mscoree里面的一個方法。而mscoree只是選擇加載CLR版本的一個Loader

之后,就跳轉到了選擇了特定版本了的mscorwks里面的_CorExeMain中:

0012ffb0 79011b5f mscorwks!_CorExeMain+0x11b

sscli中,這個程序的名字就換成了_CorExeMain2來顯示對商業版本的區別。打開CorExeMain的定義:

?

__int32 STDMETHODCALLTYPE _CorExeMain2(? // Executable exit code.

??? PBYTE? ?pUnmappedPE,????????????? ???// -> memory mapped code

??? DWORD?? cUnmappedPE,?????????? ????// Size of memory mapped code

??? __in LPWSTR? pImageNameIn,????????? // -> Executable Name

??? __in LPWSTR? pLoadersFileName,? ????// -> Loaders Name

__in LPWSTR? pCmdLine)??????????? // -> Command Line

?

?????? Load這個應用程序的image的時候,這個entry point是從native entry point中被call的。在_CorExeMain2中,我們可以看到如下部分屬性和方法:

__int32 STDMETHODCALLTYPE _CorExeMain2( …)?????????

{

??? // This entry point is used by clix

??? BOOL bRetVal = 0;

?

??? // Before we initialize the EE, make sure we've snooped for all EE-specific

??? // command line arguments that might guide our startup.

??? HRESULT result = CorCommandLine::SetArgvW(pCmdLine);

?

??? if (!CacheCommandLine(pCmdLine, CorCommandLine::GetArgvW(NULL))) {

??????? LOG((LF_STARTUP, LL_INFO10, "Program exiting - CacheCommandLine failed\n"));

??????? bRetVal = -1;

??????? goto exit;

??? }

?

??? if (SUCCEEDED(result))

??????? result = CoInitializeEE(COINITEE_DEFAULT | COINITEE_MAIN);

??? if (FAILED(result)) {

??????? VMDumpCOMErrors(result);

??????? SetLatchedExitCode (-1);

??????? goto exit;

??? }

?

??? // Load the executable

??? bRetVal = ExecuteEXE(pImageNameIn);

?

if (!bRetVal) {

?????? //這里,如果出現錯誤的話,可能的原因不正確的metadata文件的格式,或者其版本,可能是loadmscorwks的版本不正確造成的。也可能是signed assemblies和對應的錯誤處理程序不匹配造成的。總之,運行正確的話,是不會走到這里的。這個地方也可以作為CLR在開發的時候調試下斷點的一個地方。

??????? EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN2_FAILED_TEXT, IDS_EE_COREXEMAIN2_FAILED_TITLE);

??????? SetLatchedExitCode (-1);

??? }

?

//當程序走到這個地方的時候,it is the time to shut off the lights and went home了。這些都是程序退出的時候的執行的動作。

exit:

??? STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());

??? STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMain2");

??? EEPolicy::HandleExitProcess();???

??? //END_ENTRYPOINT_VOIDRET;

??? return bRetVal;

}

?

OK,從上面的程序里面,我們大概看到了一個托管模塊的生命周期。所以,最關鍵的一句就在這里了:

bRetVal = ExecuteEXE(pImageNameIn);?

這一行,也就是對應這上面堆棧調用的倒數第四行了。

??????

接下來讓我們看看這個ExecuteEXE方法都做了些什么吧:

BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod)

{

??? if (!hMod)

??????? return FALSE;

?

??? ETWTraceStartup::TraceEvent(ETW_TYPE_STARTUP_EXEC_EXE);

??? TIMELINE_START(STARTUP, ("ExecuteExe"));

?

??? EX_TRY_NOCATCH

??? {

??????? // Executables are part of the system domain

??????? SystemDomain::ExecuteMainMethod(hMod);

??? }

??? return TRUE;

}?

?????? 運行到這里,就可以看到,SystemDomain已經啟動,同時開始執行Main方法。繼續查看上面的調用堆棧:

?

0012f7e0 79f082a9 mscorwks!ClassLoader::RunMain+0x220

0012fa48 79f0817e mscorwks!Assembly::ExecuteMainMethod+0xa6

0012ff18 79f07dc7 mscorwks!SystemDomain::ExecuteMainMethod+0x398

??????

可以看到,繼SystemDomain之后,又將Assembly load到了Domain中,最后是用ClassLoader來執行Main程序。這里就不一一展示其實現了。

?????? 在執行了RunMain方法的時候,這時下面的三個堆棧:

?

0012f510 79e88e31 mscorwks!CallDescrWorkerWithHandler+0xa3

0012f650 79e88d19 mscorwks!MethodDesc::CallDescr+0x19c

0012f668 79e88cf6 mscorwks!MethodDesc::CallTargetWorker+0x20

0012f67c 79f084b0 mscorwks!MethodDescCallSite::Call+0x18

??????

?????? 在前面的上一篇文章中已經說過,MethodDescmethodtableEEClassMethodDescChunk這些結構的關系和區別。MethodDescCLR中對應的托管方法的非托管的結構。

?????? 下面的三個方法,主要是實現了定位和尋找Call Target,負責托管代碼的編譯等工作。

CallDescrWorkerWithHandler是調用的一個外部C語言編寫的函數,Call這個方法的目的,是為了把MethodTable與操作系統平臺相關的Exception Handle程序聯系起來。

?

最后的堆棧最上面的幾行:

?

0012f3c4 7b08432d USER32!NtUserWaitMessage+0xc

0012f434 7b08416b System_Windows_Forms_ni+0xb432d

0012f464 7b0c69fe System_Windows_Forms_ni+0xb416b

0012f490 79e88ee4 System_Windows_Forms_ni+0xf69fe

?

這個地方首先調用了System.Windows.Forms.NI中來初始化Winform的顯示。這里的ni后綴表面調用的是nGen函數。最后停在USER32!NtUserWaitMessage上面,等待用戶的操作。

?

這里的分析,只是展示了一個WinForm在執行完畢之后的調用堆棧。里面有很多和ThreadJITGC相關的功能的初始化和額外線程的啟動,譬如,主線程創建FinalizerThreadGCThread,由于沒有下斷點跟蹤,所以這里都沒有展現出來。

此文的主要目的,在于提供一種閱讀和分析Rotor的方法,讓對Rotorsscli)的分析,不僅僅限制與對靜態代碼的分析,我們還可以結合DotNet應用程序的運行,動態的分析代碼的執行和實現。

同時,研究不同類型應用程序調用堆棧,里面還有非常多有意思的東西可以發掘。

?

3/25/2008 10:38:33 AM

?

總結

以上是生活随笔為你收集整理的WinDbg+Rotor解析WinForm调用堆栈及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线观看超碰 | 美女精品网站 | 国产精品国产精品国产专区蜜臀ah | 成人午夜免费观看 | 伊人久久精品一区二区三区 | 日韩美在线 | 男阳茎进女阳道视频大全 | 边添小泬边狠狠躁视频 | 亚洲精品在线视频观看 | 无码一区二区三区视频 | 97成人精品视频在线观看 | 高清无打码| 国产精品免费视频一区二区三区 | 国产一级高清 | 手机在线不卡av | 成人午夜免费电影 | 久久爱网| 中文字幕在线播放第一页 | 我我色综合 | 国产色频| 成人毛片100免费观看 | 成人免费视频免费观看 | 国产亚洲精品久 | 午夜亚洲视频 | 成人午夜激情影院 | 欧美特级a | 日韩va亚洲va欧美va久久 | 久久国产成人精品国产成人亚洲 | 麻豆视频在线观看免费网站黄 | 成人久久精品人妻一区二区三区 | 国产精品呻吟 | 三级中文字幕 | 干一夜综合 | 91大神视频在线播放 | 亚洲精品一区二区三区在线 | 天堂在线中文8 | 国产日产精品一区二区三区 | 影音先锋黑人 | 99riav视频 | 欧美性受xxxx | 中文字幕永久在线观看 | 日本熟妇成熟毛茸茸 | 亚洲free性xxxx护士白浆 | 麻豆疯狂做受xxxx高潮视频 | 国产在线青青草 | 国产人人看 | 亚洲精品短视频 | 福利姬在线观看 | 能看的av网站 | 国产精品黄色大片 | 欧美视频在线免费 | www.成人| 91小视频在线观看 | 日韩特黄一级片 | av观看免费| 婷婷激情视频 | 日韩亚洲欧美精品 | 99久久婷婷国产综合精品草原 | 青娱乐国产在线 | 欧美三级又粗又硬 | 欧洲成人在线视频 | 尹人av| a黄视频 | 韩日黄色片 | 深夜成人在线 | 人妻丰满熟妇岳av无码区hd | 日韩国产毛片 | 人人亚洲 | 国产精品黄色av | 成人欧美一区二区三区黑人一 | 国产小视频你懂的 | 正在播放一区 | 三级黄色短视频 | 久久精品99国产 | 天天操天天操天天操 | 日韩一区在线免费观看 | 男男野外做爰全过程69 | 欧美 亚洲 一区 | 日本成人免费在线 | 日韩精品一区二区三区中文在线 | 欧美成人三区 | 久久久久久久偷拍 | 一级少妇女片 | 超碰在线人人干 | 同心兄弟| 精品少妇一区二区三区密爱 | 成人黄色电影在线 | 狠狠干综合网 | 亚洲风情亚aⅴ在线发布 | 激情女主播 | 国产精品无码久久久久高潮 | 久久久精品国产免费爽爽爽 | 黄色国产在线视频 | 一级片网址 | 欧美在线天堂 | 综合天天色 | 国产乱淫av麻豆国产免费 | 色中文网 | 日韩亚射吧 |