本主題描述如何使用 EXDI 設定內核模式偵錯。 擴充偵錯介面 (EXDI) 是軟體調試程式與偵錯目標之間的適應層。
從 Windows 版本 22000 開始,Windows 偵錯工具支援使用 EXDI 進行核心偵錯。
從 1.2410.11001.0 版開始,調試程式中提供設定 EXDI 的使用者介面。
EXDI 可用來建立與 QEMU 虛擬環境的連線。 如需詳細資訊,請參閱 使用EXDI設定QEMU內核模式偵錯。
注意
EXDI 是特定環境的進階特製化偵錯形式。 使用標準 KDNET 連線更容易設定,而且建議使用。 若要自動設定網路偵錯,請參閱 自動設定 KDNET 網路核心偵錯。
EXDI COM 伺服器概觀
EXDI 是一個介面,藉由新增對硬體除錯器的支援(例如 JTAG 型或 GdbServer 型)來擴充 WinDbg。 下圖說明 EXDI-GdbServer 的角色。
COM 伺服器是指實作 COM 介面的二進位元件。 在此情況下,ExdiGdbSrv.dll針對 Windows 調試程式通訊協定用戶端實作 exdi3.idl。
ExdiGdbsrv.dll本身會實作 GDB-RSP 通訊協定的用戶端 GDB 伺服器端(或有時稱為 GDB 伺服器存根),是由 QEMU GDB 伺服器實作(或 Trace32/OpenOCD/UEFI GDB 伺服器存根等)
EXDI 連線不依賴 Windows 系統或是目標電腦上所載入的 Windows 偵錯 KDNET 通訊協定。 由於不需要這些軟體調試程式元件,因此EXDI在早期裝置啟動和偵錯OS啟動問題中很有用。
重要
由於 EXDI 不會使用 KDNET 通訊協定,因此連線的調試程式對於電腦上執行的內容明顯較少,而且許多命令的運作方式不同,或完全無法運作。 存取所偵錯程式代碼的私人符號,可協助調試程序進一步瞭解目標系統程式代碼執行。 如需詳細資訊,請參閱 公用和私人符號。
EXDI 核心模式裝置需求
執行調試程式的計算機稱為 主計算機,而偵錯的計算機稱為 目標計算機。
需要下列事項:
在目標與主機計算機上,需要使用由所需環境(例如 QEMU)支援的網路卡。
目標與主機之間的網路連線,使用 TCP/IP。
Windows 10 或 Windows 11 版本 22000 或更新版本。
限制
如上所述,因為EXDI不會使用 KDNET 通訊協定,因此連線的調試程式對於目標系統的資訊較少,而且調試程式的使用方式不同。 若無法存取目標程式代碼的私人符號,許多使用符號來瞭解目標系統狀態的命令將無法運作。 在此情況下,可以檢視記憶體並註冊內容和反組譯碼。 判斷執行程序代碼的位置,或執行其他常見的調試程式工作,可能非常困難且耗時,而不需要私用符號。
同時進行 EXDI 和 KDNET 偵錯
在某些複雜的案例中,例如在早期裝置啟動時,與目標裝置建立兩個聯機會很有用。 一個 EXDI 和一個 KDNET。 如果目標是 Windows 作業系統,KDNET 軟體偵錯會如常設定,例如以連接虛擬機器的方式。 在此設定中,這兩個並行偵錯程式中的任一個都可以中斷進行偵錯,以檢查目標電腦上的程式。
進程伺服器中的 WinDbg
二進位EXDI元件可以在Windbg進程外或Windbg進程內執行。 藉由減少 COM 啟動錯誤,使用 EXDI UI 或 Inproc=<EXDI COM server binary> 大幅改善可靠性。 因此,通常建議使用 Inproc 參數來執行 EXDI 會話,使用 UI 時該參數會一律啟用。
針對命令行啟動,預設選項已脫離進程,但應該使用 InProc=ExdiGdbDrv.dll 參數來啟用 inprocess。
COM GDB 伺服器用戶端
本主題描述使用實作 EXDI COM 調試程式介面的 EXDI COM GDB 伺服器用戶端 (ExdiGdbSrv.dll)。 您可以使用相同的 COM 介面來實作其他介面,例如適用於 JTAG-DCI 的 EXDI COM 伺服器。
使用 EXDI 連線的程式摘要
使用此流程,以搭配 WinDbg 使用 EXDI 連線。
- 在主機系統上下載並安裝 Windows 偵錯工具。
- 使用 UI 或 -kx 選項啟動 WinDbg,以連線到 EXDI 伺服器。
- 使用 WinDbg,使用一組可用的調試程式命令對目標系統進行偵錯。
如需EXDI使用案例的範例,請參閱 使用EXDI設定QEMU內核模式偵錯。
下載並安裝 Windows 偵錯工具
在主機系統上安裝 Windows 偵錯工具。 如需下載及安裝調試程式工具的資訊,請參閱 Windows 的偵錯工具。
啟動 WinDbg 並連線到 EXDI 伺服器
您可以在 EXDI 核心連線 UI 中設定下列選項。
目標類型
[Trace32|BMC-OpenOCD|QEMU|VMware|UEFI]根據您要偵錯的目標類型選取。 下列目標類型可供使用。- Trace32 :Lauterbach Trace32 HW 調試程式 GDB 伺服器組態
- BMC-OpenOCD :BMC-OpenOCD HW 調試程式 GDB 伺服器組態
- QEMU:QEMU SW 模擬器 GDB 伺服器設定
- VMware:VMware GDB 伺服器組態
- UEFI:UEFI 韌體偵錯
目標架構
[x86 | ARM64 | x64]- 目標處理器架構。 請注意,所有目標類型都可能不支援所有目標架構。目標OS
[Windows|Linux]- 根據您要偵錯的目標OS選取。影像掃描啟發學習法大小
[None | 0xFE - PreNT |0xFFE - NT]- 選取三個選項之一,以判斷影像掃描的啟發學習大小。 這個值會設定調試程式引擎如何掃描尋找PE DOS簽章的記憶體,該簽章是用來收集程式代碼執行狀態。 如果未指定屬性值 (或 “0),調試程式引擎就不會使用快速啟發學習法,並回復到掃描整個記憶體尋找 PE DOS 簽章的舊版啟發學習法。 系統會針對每個目標類型選取預設值,並建議使用。Gdb 伺服器和埠
TargetIPAddress:TargetPortAddress- 設定為一個字串,該字串應包含 IPTargetAddress、冒號和目標 PortAddress。 例如:LocalHost:1234或168.82.1.5:5555。中斷聯機
[on|off]選取複選框以在建立連線之後中斷目標。進階選項
顯示通訊封包記錄
[on|off]- 選取複選框,以顯示原始 GDBServer 通訊封包記錄檔中的十六進位值,以進行偵錯和疑難解答。
選取所需的選項之後,請選取 [ 確定 ] 以連線。
使用 EXDI 組態 XML 檔案設定進階選項
本主題所述的使用者介面中提供所需的大部分選項。 如需使用EXDI組態 XML 檔案設定進階選項的詳細資訊,請參閱 EXDI XML 組態檔。
WinDbg 命令行 EXDI 範例
若要在命令提示字元中啟動使用 EXDI 介面的 WinDbg 工作階段,請使用以下選項。
c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,InProc=ExdiGdbDrv.dll,DataBreaks=Exdi
若要顯示適用於診斷用途的其他輸出,可以使用-v:詳情會話。 如需 WinDbg 選項的一般資訊,請參閱 WinDbg 命令行選項。 如需詳細資訊,請參閱 下面的EXDI WinDbg 載入參數 。
調試程式主控台會顯示 EXDI 傳輸初始化。
EXDI: DbgCoInitialize returned 0x00000001
EXDI: CoCreateInstance() returned 0x00000000
EXDI: QueryInterface(IExdiServer3) returned 0x00000000
EXDI: Server::GetTargetInfo() returned 0x00000000
EXDI: Server::SetKeepaliveInterface() returned 0x00000000
EXDI: Server::GetNbCodeBpAvail() returned 0x00000000
EXDI: ExdiNotifyRunChange::Initialize() returned 0x00000000
EXDI: LiveKernelTargetInfo::Initialize() returned 0x00000000
EXDI: Target initialization succeeded
Kernel Debugger connection established
EXDIGdbServer 控制台視窗也可以顯示 EXDI 連線狀態的相關信息。 如需主控台的詳細資訊,請參閱 疑難解答。
EXDI WinDbg 載入參數
下列參數會與 WinDbg 一起使用,來啟動 EXDI 核心模式會話。
-kx EXDI:Options
下列 EXDI 選項適用於 -kx 選項。 每個選項都應該使用逗號分隔。
| 參數 | 描述 |
|---|---|
| CLSID | 指派給 LiveExdiGdbSrvServer 的類別標識碼(如ExdiGdbSrv.idl 檔案中所定義)。 |
| Kd=Guess -or- NtBaseAddr | 調試程式引擎會使用一般啟發學習機制 -或- 尋找 NT 基位址。 |
| ForceX86 | 強制調試程式引擎使用 IeXdiX86Context3 介面來取得/設定 CPU 內容。 |
| DataBreaks=Exdi | 允許使用數據斷點。 |
| Inproc | 允許使用 inproc Exdi-Server。 建議使用此選項 - InProc=ExdiGdbDrv.dll |
| 伺服器配置檔路徑 (PathToSrvCfgFiles) | EXDI 之 XML 組態檔的路徑。 |
控制啟發學習法搜尋和啟發學習法大小
如先前所述,調試程式會使用啟發學習法演算法來找出NT基位址。 若要取消啟發學習法搜尋,請在透過命令行啟動 WinDbg 時,完成下列步驟。
- 在您要附加的目標伺服器exdiconfigdata.xml檔案中,將啟發式ScanSize 設定為 0。
- 在Windbg命令行中使用
kd=NtBaseAddr啟發式類型。
如需使用 XML 組態檔的詳細資訊,請參閱 EXDI XML 組態檔。
使用 WinDbg 對目標系統進行偵錯 - 斷點
dbgeng.dll會使用啟發學習演算法來尋找發生中斷命令時 NT 基底負載位址的位置。 如果私人符號無法使用,此過程將會失敗。
這表示在許多連接順序下,中斷將無法如預期般運作。 如果您手動中斷程式代碼,則會是 Windows 當時所執行的隨機位置。 由於目標程式代碼的符號可能無法使用,因此很難使用符號來設定斷點。
調試程式命令
如以下命令直接存取記憶體將能正常運作。
k, kb, kc, kd, kp, kP, kv (顯示堆棧回溯)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (顯示記憶體)
您可以使用 p (Step) 逐步執行程式碼。
也有一個命令可用來嘗試尋找您想要偵錯的程序代碼。
Imgscan 可以幫助進行 EDXI 偵錯,因為與傳統基於 KDNET 的核心偵錯不同,依據符號設定斷點可能不可用。 尋找所需的目標映像,有助於使用其位置來設定記憶體取斷點。
.exdicmd (EXDI 命令)
.exdicmd 會使用作用中的 EXDI 偵錯連線,將 EXDI 命令傳送至目標系統。 如需詳細資訊,請參閱 .exdicmd (EXDI 命令) 。
疑難排解
使用 ExdiGdbServer 視窗的輸出來監視連接順序。
問題:錯誤:無法建立與 GbDServer 的連線。 確認 連接字串 <hostname/ip>:portnumber
此問題可能是由下列原因所造成:
- ExdiGdbSrv.dll無法連線到目標 GDB 伺服器。
- GDB 伺服器尚未在目標系統上運行。
- 防火牆問題,請確定這兩個IP位址都可以透過 ping、tracert 或其他工具來確認 GDB 流量可以通過防火牆。
問題:目標系統的錯誤場景無法使用 - DbgCoInitialize 傳回 0x00000001
如果未載入目標系統或無法使用,可能會傳回下列輸出。
Microsoft (R) Windows Debugger Version 10.0.20317.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
EXDI: DbgCoInitialize returned 0x00000001
當 ExdiGdbSrv.dll COM 伺服器無法連線到 QEMU GDServer 時,這是常見的錯誤,因此可能會因為下列原因而失敗:
ExdiGdbSrv.dll的上一個會話仍由dllhost.exe進程裝載,因此您必須終止dllhost.exe程式。 在命令提示字元中使用
TaskList,找出裝載ExdiGdbSrv.dll之dllhost.exe的 PID。 使用TaskKill /PID <PID ID> /f並終止相關聯的 PID。 如需使用 PID 的詳細資訊,請參閱 尋找進程識別碼。QEMU gdbserver 尚未啟動,或exdiconfigdata.xml檔案包含無效的IP:Port 值。 如果 WinDbg 工作階段在與 QEMU Windows VM 相同的主電腦中啟動,則 IP=LocalHost。
透過dllhost.exe程式(COM 相關)啟動 EXDI COM 伺服器(ExdiGDbSrv.dll)失敗。 若要解決此問題,請重新啟動主機調試程式計算機或註銷 Windows,然後再次登入。 如果無法運作,請在重新啟動/登入后重新註冊 EXDI COM 伺服器。
regsvr32.exe <full path to the ExdiGdbSrv.dll)
問題:無法啟動偵錯會話:FAILURE HR=0x80004005:Failed to AttachKernel。
此問題可能是由下列原因所造成:
- 如上所述,ExdiGdbSrv.dll 的先前會話可能仍處於活動狀態。 找出並終止相關聯的 DLL 主機,如上所述。
問題:無法使用EXDI啟動核心偵錯。
此問題可能是由下列原因所造成:
- 在主機上的調試器機器上,另一個由 dllhost.exe 託管的 ExdiGdbSrv.dll 實例正在運行。
- 終止裝載ExdiGdbSrv.dll之 COM 服務的額外實例。
- 首先列出進程,使用主機計算機上的 TList 之類的公用程式。 裝載ExdiGdbSrv.dll的 DLLHost 會顯示 ExdiGdbServer。
tlist 261928 dllhost.exe ExdiGdbServer
- 在
kill -f XXXXX調試程式命令提示字元中使用 ,以使用進程號碼終止進程。
- 首先列出進程,使用主機計算機上的 TList 之類的公用程式。 裝載ExdiGdbSrv.dll的 DLLHost 會顯示 ExdiGdbServer。
問題:錯誤:無法設定 GdbServer 會話。
此問題可能是由下列原因所造成:
- 尋找工作階段資訊時發生錯誤,例如 XML 組態檔的路徑。
問題:錯誤:未定義EXDI_GDBSRV_XML_CONFIG_FILE環境變數。
此問題可能是由下列原因所造成:
- ExdiGdbSrv.dll未設定環境變數,或無法在環境中使用。
問題:錯誤:未定義EXDI_GDBSRV_XML_CONFIG_FILE環境變數。 Exdi-GdbServer 範例目前不會繼續。 設定 Exdi XML 組態檔的完整路徑。
此問題可能是由下列原因所造成:
- 未設定EXDI_GDBSRV_XML_CONFIG_FILE環境變數。 在某些情況下,如果您按下 [確定] 按鈕,ExdiGDbSrv.dll 會繼續運作,但 windbg.exe 會失敗查詢系統暫存器(例如通過 rdmsr/wrmsr 函式)。