用WinDbg探索CLR世界 2 執行緒

2021-04-12 16:55:28 字數 2737 閱讀 4844

[2] 執行緒

在配置好windbg之後,我們載入乙個clr程式並執行至clr被載入,然後開始我們的clr探索之旅。

首先,使用!threads命令看看當前clr中有哪些執行緒正在執行

以下為引用:

0:004> !threads

threadcount: 2

unstartedthread: 0

backgroundthread: 1

pendingthread: 0

deadthread: 0

preemptive   gc alloc               lock

id threadobj    state     gc       context       domain   count apt exception

0   6ec 0014e708      6020 enabled  00000000:00000000 00148a90     0 sta

2   a68 00157618      b220 enabled  00000000:00000000 00148a90     0 mta (finalizer)

.net

framework

sdk 的tool developers guide/samples/sos子目錄下找到所有sos.dll支援命令的詳細說明;在rotor的clr/ src/tools/sos子目錄下找到針對rotor系統的sos.dll的實現**。這份源**在功能上實現了與clr正規發行版本基本上相同的功能,也是我們下面研究的主要目標之一。

其中strike.cpp是sos功能命令的實現所在。每個sos的命令在strike.cpp中以乙個函式實現,通過declare_api巨集定義函式引數。

以下為引用:

#define declare_api(s)                             /

cppmod void                                    /

s(                                             /

handle                 hcurrentprocess,    /

handle                 hcurrentthread,     /

ulong                  dwcurrentpc,        /

ulong                  dwprocessor,        /

pcstr                  args                /

)

函式引數分別傳入windbg正在除錯的程序控制代碼、當前執行緒控制代碼、當前指令位址、處理器和命令列引數資訊。函式內再對此資訊進行處理,輸出除錯資訊到windbg介面中。

讓我們先看看threads命令(strike.cpp:1237)的實現原理。

threads 函式首先從乙個全域性執行緒儲存池中獲取當前執行緒統計資訊,並將之儲存在乙個結構並內列印統計值;然後呼叫getthreadlist函式(sos/ util.cpp:2259)獲取執行緒列表;對每個執行緒獲取執行緒資訊,並將之儲存在乙個結構內並列印執行緒詳細資訊;在列印執行緒資訊時,會判斷此執行緒的型別,並列印相關資訊。

首先來看看全域性執行緒儲存池threadstore類(vm/threads.h:1998)的設計和使用思路。

clr 在啟動時,會通過 coinitializeee 函式(vm/ceemain.cpp:1100)初始化乙個執行引擎 (execute engine),這兒的ee類似jvm的概念,實際上就是clr的執行時環境。關於clr的詳細啟動過程請參見筆者另外一篇文章

《.net平台下clr程式載入原理分析》

。coinitializeee函式使用全域性變數保障每個程序最多只有乙個clr環境;對沒有構造clr的程序,呼叫tryeestartup函式(vm/ceemain.cpp:500)嘗試初始化clr。偽**如下:

以下為引用:

hresult stdmethodcalltype coinitializeee(dword fflags)

return succeeded(g_eestartupstatus) ?

(setupthread() ? s_ok : e_outofmemory) : g_eestartupstatus;

}

tryeestartup函式則以異常安全策略包裝eestartup函式(vm/ceemain.cpp:206)完成實際的clr啟動工作。在eestartup函式中會真正呼叫initthreadmanager函式(vm/threads.cpp:2068)完成執行緒管理器的初始化工作。而initthreadmanager函式出了初始化tls外,絕大部分工作是由實現threadstore類的 singleton模式的threadstore::initthreadstore函式(vm/threads.cpp:4345)實現的。其中儲存全域性唯一threadstore類例項的就是前面獲取執行緒統計資訊的全域性執行緒儲存池。

以下為引用:

threadstore *g_pthreadstore;

bool threadstore::initthreadstore()

windbg 用WinDbg探索ruby的奧秘

寫這篇文章是受 url 從main.c開始走進ruby 登上除錯ruby之旅 url 的啟發,不同的是該文章用的是gdb,gdb雖然很強大,但是畢竟是命令列,在除錯的時候,可能同時需要檢視許多資訊,比如call statck,彙編 源 等等,命令列就有點力不從心,所以續寫一篇,改gdb為同樣強大的w...

探索物件導向的世界

文章目錄 隨著我們不斷的學習,物件導向的思想被我們應用了起來,它不僅應用在程式設計和軟體開發上,同樣也擴充套件到了資料庫,人工智慧等領域 物件導向是一種對現實世界理解和抽象的方法,是計算機程式設計技術發展到一定階段後的產物 相對於面向過程來講,它將一些方法和資料當成乙個整體來看待,從更高層次進行抽象...

用 WinDbg 診斷CPU占用高

2.安裝windbg,這個就不贅述了。需要注意的是有 windbg x64 和 windbg x86 兩個,應該按dmp檔案 的伺服器開啟。3.按 ctrl d 開啟 dmp 檔案,注意直接點那個工具欄上的開啟檔案的圖示是錯誤的。4.載入 sos.dll 檔案。這個最好是直接把 dmp 檔案 伺服器...