2014-01-18 35 views
5

瀏覽一些論壇上,我跨this answer來到其中回答者是指以下爲本地調用堆棧與CLR有關的本地調用堆棧究竟是什麼?

00000000`0014ea10 00000642`7f67d4a2 0x642`80150142 
00000000`0014ea90 00000642`7f5108f5 mscorwks!CallDescrWorker+0x82 
00000000`0014eae0 00000642`7f522ff6 mscorwks!CallDescrWorkerWithHandler+0xe5 
00000000`0014eb80 00000642`7f49a94b mscorwks!MethodDesc::CallDescr+0x306 
00000000`0014edb0 00000642`7f474ae4 mscorwks!ClassLoader::RunMain+0x23f 
00000000`0014f010 00000642`7f5efb1a mscorwks!Assembly::ExecuteMainMethod+0xbc 
00000000`0014f300 00000642`7f467d97 mscorwks!SystemDomain::ExecuteMainMethod+0x492 
00000000`0014f8d0 00000642`7f482c24 mscorwks!ExecuteEXE+0x47 

究竟是關於本地調用堆棧的CLR(在這裏我們看CLR調用我認爲的主要方法)以及如何查看和理解本地機器上的本機調用堆棧以用於教育目的?

回答

10

是的,這些是非託管用C++編寫的函數。用於編寫CLR的語言。

與託管代碼使用堆棧相比,非託管代碼使用堆棧的方式沒有根本區別。唯一的區別是,您需要一個非託管調試器來實際上請參閱堆棧跟蹤中的非託管函數。託管調試器只報告堆棧跟蹤中的[託管到本地轉換]並隱藏非託管功能。

哪個是有生產力的,你通常不感興趣的非託管代碼,可能會錯過所需的PDB,使跟蹤準確。其中,對於CLR,需要啓用Microsoft Symbol Server。託管堆棧跟蹤始終是準確的,因爲垃圾收集器和CAS需要執行堆棧遍歷才能完成他們的工作,所以CLR提供了硬性保證,堆棧走線可以很好地工作。由於C++代碼生成器的優化,非託管堆棧跟蹤更加困難,例如,幀指針省略優化對堆棧行走來說非常致命。

你當然可以看到兩者。項目+屬性,調試選項卡,勾選「啓用本地代碼調試」選項。

+0

巨大的答案。謝謝。 –

3

「本地調用堆棧」表示調用堆棧的一部分(通過非託管庫)。由於操作系統不受管理,因此總是有一些非託管入口指向託管堆棧。但是,您也可以在其之上有非託管方法,即,如果託管代碼調用到系統函數中。調用堆棧可以包含任意數量的託管到本機和本機到託管的轉換。要看到合理的東西,應該打開「非託管調試」。

在上例中,您會看到調用源自mscorwks.dll,它是包含.NET執行引擎的主dll。由於缺少該庫的符號(除非您已經下載了它們 - 請參閱google上的「Microsoft符號服務器」),因此您只需要注意不同功能的入口點。作爲mscorwks!CallDescrWorkerWithHandler+0xe5的行表示該調用源自mscorwks.dll中名爲「CallDescrWorkerWithHandler」的函數,該函數的起始位置爲0xe5個字節。