<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WinDbg+Rotor解析WinForm調(diào)用堆棧及實現(xiàn)

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

      這次,寫一篇文章,結(jié)合Windbg,從一個托管應(yīng)用程序執(zhí)行的調(diào)用堆棧開始,追蹤其調(diào)用堆棧中的線索,以及這些托管應(yīng)用程序執(zhí)行中調(diào)用的功能實現(xiàn),來展示托管代碼的加載和執(zhí)行的流程和實現(xiàn)。

      首先還是找一個小白鼠:

       

           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應(yīng)用程序來作為小白鼠。

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

       

      打開Windbg,附加到進(jìn)程,加載好相關(guān)的symbol2.0SOS,切換到第0Thread然后輸出其調(diào)用堆棧:

       

      0:000> k

      ChildEBP RetAddr 

      0012f4a0 7c92e9ab ntdll!KiFastSystemCallRet

      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 79011b5f mscorwks!_CorExeMain+0x11b

      0012ffc0 7c816fd7 mscoree!_CorExeMain+0x2c

      0012fff0 00000000 KERNEL32!BaseProcessStart+0x23

       

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

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

      0012ffb0 79011b5f mscorwks!_CorExeMain+0x11b

      sscli中,這個程序的名字就換成了_CorExeMain2來顯示對商業(yè)版本的區(qū)別。打開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這個應(yīng)用程序的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) {

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

              EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN2_FAILED_TEXT, IDS_EE_COREXEMAIN2_FAILED_TITLE);

              SetLatchedExitCode (-1);

          }

       

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

      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,從上面的程序里面,我們大概看到了一個托管模塊的生命周期。所以,最關(guān)鍵的一句就在這里了:

      bRetVal = ExecuteEXE(pImageNameIn); 

      這一行,也就是對應(yīng)這上面堆棧調(diào)用的倒數(shù)第四行了。

            

      接下來讓我們看看這個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;

      } 

             運(yùn)行到這里,就可以看到,SystemDomain已經(jīng)啟動,同時開始執(zhí)行Main方法。繼續(xù)查看上面的調(diào)用堆棧:

       

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

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

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

            

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

             在執(zhí)行了RunMain方法的時候,這時下面的三個堆棧:

       

      0012f510 79e88e31 mscorwks!CallDescrWorkerWithHandler+0xa3

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

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

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

            

             在前面的上一篇文章中已經(jīng)說過,MethodDescmethodtableEEClassMethodDescChunk這些結(jié)構(gòu)的關(guān)系和區(qū)別。MethodDescCLR中對應(yīng)的托管方法的非托管的結(jié)構(gòu)。

             下面的三個方法,主要是實現(xiàn)了定位和尋找Call Target,負(fù)責(zé)托管代碼的編譯等工作。

      CallDescrWorkerWithHandler是調(diào)用的一個外部C語言編寫的函數(shù),Call這個方法的目的,是為了把MethodTable與操作系統(tǒng)平臺相關(guān)的Exception Handle程序聯(lián)系起來。

       

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

       

      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

       

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

       

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

      此文的主要目的,在于提供一種閱讀和分析Rotor的方法,讓對Rotorsscli的分析,不僅僅限制與對靜態(tài)代碼的分析,我們還可以結(jié)合DotNet應(yīng)用程序的運(yùn)行,動態(tài)的分析代碼的執(zhí)行和實現(xiàn)。

      同時,研究不同類型應(yīng)用程序調(diào)用堆棧,里面還有非常多有意思的東西可以發(fā)掘。

       

      3/25/2008 10:38:33 AM

       

      posted on 2008-03-25 10:50  lbq1221119  閱讀(3762)  評論(2)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 免费超爽大片黄| 国产精品青草久久久久福利99| 94人妻少妇偷人精品| 郓城县| 九九热在线免费视频观看| 99精品热在线在线观看视| 恩平市| 亚洲成女人图区一区二区| 亚洲欧洲色图片网站| 亚洲五月丁香综合视频| 国产精品自在拍首页视频| 万全县| 国产精品线在线精品国语| 久爱无码精品免费视频在线观看 | 东方四虎av在线观看| 国产精品污一区二区三区| 国产精品久久久久久久专区| 日韩精品一区二区三区在| 亚洲人成影院在线观看| 亚洲精品无码成人A片九色播放 | 日韩乱码人妻无码中文字幕| 国内少妇人妻偷人精品视频| 亚洲中文字幕国产综合| 洪洞县| 精品人妻伦九区久久69| 亚洲中文字幕伊人久久无码 | 在办公室被c到呻吟的动态图| 天天做天天爱夜夜爽导航| 天天综合色一区二区三区| 18岁日韩内射颜射午夜久久成人| 日韩人妻中文字幕精品| 益阳市| 亚洲精品乱码久久久久久中文字幕 | 最新精品国偷自产在线 | 国产欧美日韩视频怡春院| 亚洲男人天堂2018| 亚洲国产精品久久久天堂麻豆宅男 | 久久老熟女一区二区蜜臀| 色哟哟www网站入口成人学校| 兔费看少妇性l交大片免费| 日本久久99成人网站|