共用方式為


EXDI XML 組態檔

本主題描述如何使用 EXDI XML 組態檔設定進階選項。 如需使用 WinDbg 使用者介面設定 EXDI 的一般資訊,請參閱 設定 EXDI 調試程式傳輸。 最常見的設定可在使用者介面中使用,這是一種更簡單的方法,然後手動編輯 EXDI XML 組態檔,如下所述。

擴充偵錯介面 (EXDI) 是軟體調試程式與偵錯目標之間的適應層。 從 Windows 版本 22000 開始,Windows 偵錯工具支援使用 EXDI 進行核心偵錯。

注意

EXDI 是特定環境的進階特製化偵錯形式。 使用標準 KDNET 連線更容易設定,而且建議使用。 若要自動設定網路偵錯,請參閱 自動設定 KDNET 網路核心偵錯

使用 EXDI 組態 XML 檔案設定進階選項

EXDI GDB COM 伺服器會取用兩個必要的 xml 檔案(ExdiGdbSrv.dll)。

  1. exdiConfigData.xml - 此檔案包含 GDB 伺服器用戶端使用 HW 調試程式 GDB 伺服器目標建立成功 GDB 工作階段所需的主要組態數據,因此如果檔案位置不是由EXDI_GDBSRV_XML_CONFIG_FILE環境變數設定,GDB 伺服器用戶端將不會執行。 每個 xml 標記都允許設定 GDB 伺服器功能的特定集合。 如需您可以在 XML 中修改的屬性清單,以及範例 XML,請參閱下方。

  2. Systemregister.xml - 此檔案包含系統快取快取緩存器的程式代碼之間的對應。 這是必要的,因為 XML 檔案中的 GDB 伺服器未提供存取碼,而調試程式會透過存取碼存取每個系統快取器。 如果檔案未透過環境變數 EXDI_SYSTEM_REGISTERS_MAP_XML_FILE設定,則ExdiGdbSrv.dll會繼續運作,但調試程式將無法透過 rdmsr 或 wrmsr 命令存取任何系統緩存器。 GDB 伺服器硬體除錯程式應該支援這些快取器的清單(特定系統快取器名稱應該出現在系統 xml 檔案中傳送的快取器清單中)。

EXDI UI 和 XML 組態檔

WinDbg 中的 EXDI UI 會使用 XML 檔案參數,並在 UI 必要參數中合併,例如 IP:Port 值。 如果需要修改預設 XML 檔案參數,請使用 參數 PathToSrvCfgFiles=<path to the modified exdiconfigdata.xml file>從命令行啟動 WinDbgNext 應用程式。

目標架構

EXDI UI 目標架構域值必須只針對未實作描述 Windows OS 目標架構之目標描述 XML 檔案的 GDB 伺服器存根,比對在目標上執行的 Windows OS。 此target.xml檔案資訊會在 GDB 用戶端與 GDB 伺服器存根之間的 GDB-RSP 通訊協定交握期間由 GDB 伺服器存根傳送。

Windbg-ExdiGdbSrv 仍然可以設定正確的目標OS架構,即使使用者在EXDI UI 中設定了不正確的目標架構字段輸入值也一樣。 目標 OS 架構將會從 GDB 伺服器所提供的target.xml描述檔中取得和設定,這些檔案包含 GDB 伺服器交握中的target.xml檔案。 若要檢查目標架構,請使用有效的計算機 .effmach 調試程序命令。

GDBServer 標記和屬性

下表描述檔案中 exdiConfigData.xml 定義的 GDBServer 標記和屬性。

參數 描述
ExdiTargets 指定ExdiGgbSrv.dll將使用哪些特定 GDB 伺服器目標組態來建立與 GDB 伺服器目標的 GDB 連線,因為exdiConfigData.xml檔案包含ExdiGdbSrv.dll目前支援的所有 GDB 伺服器(此檔案必須先填入,才能搭配特定 GDB 伺服器使用ExdiGdbSrv.dll)。
CurrentTarget 指定 GDB 伺服器目標的名稱(例如,這個屬性值應該與exdiConfigData.xml檔案所包含的其中一個 <ExdiTarget Name= 標籤名稱值相符。
ExdiTarget 這是每個 GDB 伺服器目標元件所包含之所有組態數據的開始標記。
名稱 指定 GDB 伺服器的名稱(例如 QEMU、BMC-OpenOCD、Trace32、VMWare)。
agentNamePacket 這是 GDB 伺服器 HW 調試程式所辨識的 GDB 用戶端名稱。 GDB 伺服器 HW 調試程式可以使用此程式來設定特定 GDB 用戶端的本身(例如 Trace32 GDB 伺服器需要ExdiGdbSrv.dll傳送 “QMS.windbg” 名稱來識別 windbg-GDB 用戶端,然後啟用僅支援 MS GDB 伺服器用戶端的自定義 GDB 記憶體封包(exdiGdbSrv.dll)。
ExdiGdbServerConfigData 指定ExdiGdbSrv.dll元件相關的組態參數。
uuid 指定ExdiGdbSrv.dll元件的 UUI。
displayCommPackets 如果為 『yes』,則我們會在命令記錄視窗中顯示 RSP 通訊協定通訊字元。 如果為 『no』,則只會顯示要求-回應組文字。
enableThrowExceptionOnMemoryErrors 當 GDB 錯誤回應封包 (E0x) 時,GDB 伺服器用戶端會檢查此屬性,以判斷用戶端是否應該擲回例外狀況並停止讀取記憶體。
qSupportedPacket 這可讓設定 GDB 用戶端要求在 XML 目標描述檔之後,GDB 伺服器 HW 調試程式應該傳送哪些 xml 快取器架構檔案(基本上,用戶端會通知 GDB 伺服器哪些架構受到客戶端支援,目前用戶端支援 x64 架構)。
ExdiGdbServerTargetData 指定與 GdbServer 會話偵錯的硬體目標相關的參數。
targetArchitecture 包含目標硬體架構的字串。 可能的值:X86、X64、ARM、ARM64。 目前,exdiGdbSrv.dll僅支援 X86 和 ARM。
targetFamily 包含目標硬體系列的字串。 可能的值:ProcessorFamilyX86、ProcessorFamilyX64、ProcessorFamilyARM、ProcessorFamilyARM64。
numberOfCores 目標支援的處理器核心數目。 當我們使用多 Gdbserver 會話 (T32-GdbServer 會話) 時,將會驗證此參數。 下列 'MultiCoreGdbServerSessions' 屬性應設定為 'yes'。
EnableSseContext 如果為 『yes』,則 『g』 內容 RSP 封包會包含浮點緩存器值。 此參數僅適用於 Intel 系列目標。
heuristicScanSize 這會設定調試程式引擎快速啟發學習法演算法,以減少所掃描記憶體探查的大小,如果未指定屬性值(或 “0”),則調試程式引擎不會使用快速啟發學習法,並回復到掃描整個記憶體的啟發學習法,以尋找 PE DOS 簽章。 常見的掃描大小值是0xfffe(最適合NT)或0xffe(適用於預先NT應用程式)。
targetDescriptionFile 指定 GDB 伺服器是否在傳送每個個別的 xml 檔案之前傳送目標描述頭檔。 此欄位空白,則 GDB 伺服器用戶端不會要求 xml 架構系統快取器(例如不支援在個別 xml 檔案中傳送架構快取器的 Trace32 GB 伺服器)。
GdbServerConnectionParameters 指定 GdbServer 工作階段參數。 這些參數可用來控制ExdiGdbSrv.dll元件與 GdbServer 之間的 RSP GdbServer 會話。
MultiCoreGdbServerSessions 旗標 如果為 'yes',則我們將有多核心 GdbServer 會話(T32-GdbServer 後端所使用的會話)。 如果為 『no』,則我們只會與 GdbServer 的一個實例通訊。
MaximumGdbServerPacketLength 這是一個封包所支援的最大 GdbServer 長度。
MaximumConnectAttempts 這是連線嘗試次數上限。 ExdiGdbSrv.dll嘗試建立與 GdbServer 的 RSP 連線時,會使用它。
SendPacketTimeout 這是 RSP 傳送逾時。
ReceivePacketTimeout 這是 RSP 接收逾時。
HostNameAndPort 這是格式<hostname/ip address:Port number>的 連接字串。 可以有多個 GdbServer 連接字串 (例如 T32 多核心 GdbServer 會話)。 連接字串 數目應該與核心數目相符。
ExdiGdbServerMemoryCommands 指定各種發出 GDB 記憶體命令的方式,以便取得不同例外狀況 CPU 層級的系統緩存器值或讀取/寫入存取記憶體(例如 BMC-OpenOCD 可透過 “aarch64 mrs nsec/sec <access code>” 自定義命令來存取 CP15 緩存器。
GdbSpecialMemoryCommand 如果為 「yes」,則 GDB 伺服器支援自定義的記憶體命令(例如系統快取器,這應該為 Trace32 GDB 伺服器設定)。
PhysicalMemory 如果為 「yes」,則 GDB 伺服器支援自定義命令來讀取物理記憶體(它設定為 Trace32 GDB 伺服器)。
SupervisorMemory 如果為 「yes」,則 GDB 伺服器支援自定義命令來讀取監督員記憶體(它設定為 Trace32 GDB 伺服器)。
SpecialMemoryRegister 如果為 「yes」,則 GDB 伺服器支援自訂命令來讀取系統快取器(它設定為 Trace32 GDB 伺服器)
SystemRegistersGdbMonitor 如果為 「yes」,則 GDB 伺服器會透過 GDB 監視器命令支援自定義命令(其設定為 BMC Open-OCD)。
SystemRegisterDecoding 如果為 「yes」,則 GDB 用戶端會在傳送 GDB 監視器命令之前接受譯碼。
ExdiGdbServerRegisters 指定特定的架構快取器核心集。
架構 已定義快取器集的CPU架構。
FeatureNameSupported 這是 xml 系統快取器描述檔所提供的系統快取器群組名稱。 需要識別系統註冊 xml 群組,該群組是 GDB 伺服器所傳送之 xml 檔案的一部分。
SystemRegistersStart 這是要識別作為核心緩存器集一部分回報的第一個系統緩存器(例如,在 X64 上,QEMU 不會將 x64 系統快取器集合報告為分隔的 xml 目標描述檔,因此系統 regs 是核心緩存器的一部分)。
SystemRegistersEnd 這是識別在核心緩存器集中回報的最後一個系統緩存器(高緩存器編號/順序)。
名稱 緩存器的名稱。
訂單 這是識別快取器陣列中索引的數位。 GDB 用戶端和伺服器集/查詢 (p<number>”/”q<number>) 註冊封包將會使用此數位。
大小 這是以位元組為單位的緩存器大小。

範例exdiConfigData.xml檔案

<ExdiTargets CurrentTarget = "QEMU">
<!-- QEMU SW simulator GDB server configuration -->
    <ExdiTargets CurrentTarget="QEMU">
    <!--  QEMU SW simulator GDB server configuration  -->
    <ExdiTarget Name="QEMU">
    <ExdiGdbServerConfigData agentNamePacket="" uuid="72d4aeda-9723-4972-b89a-679ac79810ef" displayCommPackets="yes" debuggerSessionByCore="no" enableThrowExceptionOnMemoryErrors="yes" qSupportedPacket="qSupported:xmlRegisters=aarch64,i386">
    <ExdiGdbServerTargetData targetArchitecture="ARM64" targetFamily="ProcessorFamilyARM64" numberOfCores="1" EnableSseContext="no" heuristicScanSize="0xfffe" targetDescriptionFile="target.xml"/>
    <GdbServerConnectionParameters MultiCoreGdbServerSessions="no" MaximumGdbServerPacketLength="1024" MaximumConnectAttempts="3" SendPacketTimeout="100" ReceivePacketTimeout="3000">
    <Value HostNameAndPort="LocalHost:1234"/>
    </GdbServerConnectionParameters>
    <ExdiGdbServerMemoryCommands GdbSpecialMemoryCommand="no" PhysicalMemory="no" SupervisorMemory="no" HypervisorMemory="no" SpecialMemoryRegister="no" SystemRegistersGdbMonitor="no" SystemRegisterDecoding="no"> </ExdiGdbServerMemoryCommands>
        <ExdiGdbServerRegisters Architecture = "ARM64" FeatureNameSupported = "sys">
            <Entry Name ="X0"  Order = "0" Size = "8" />
            <Entry Name ="X1"  Order = "1" Size = "8" />
            <Entry Name ="X2"  Order = "2" Size = "8" />
            <Entry Name ="X3"  Order = "3" Size = "8" />
            <Entry Name ="X4"  Order = "4" Size = "8" />
            <Entry Name ="X5"  Order = "5" Size = "8" />
            <Entry Name ="X6"  Order = "6" Size = "8" />
            <Entry Name ="X7"  Order = "7" Size = "8" />
            <Entry Name ="X8"  Order = "8" Size = "8" />
            <Entry Name ="X9"  Order = "9" Size = "8" />
            <Entry Name ="X10" Order = "a"  Size = "8" />
            <Entry Name ="X11" Order = "b"  Size = "8" />
            <Entry Name ="X12" Order = "c"  Size = "8" />
            <Entry Name ="X13" Order = "d"  Size = "8" />
            <Entry Name ="X14" Order = "e"  Size = "8" />
            <Entry Name ="X15" Order = "f"  Size = "8" />
            <Entry Name ="X16" Order = "10" Size = "8" />
            <Entry Name ="X17" Order = "11" Size = "8" />
            <Entry Name ="X18" Order = "12" Size = "8" />
            <Entry Name ="X19" Order = "13" Size = "8" />
            <Entry Name ="X20" Order = "14" Size = "8" />
            <Entry Name ="X21" Order = "15" Size = "8" />
            <Entry Name ="X22" Order = "16" Size = "8" />
            <Entry Name ="X23" Order = "17" Size = "8" />
            <Entry Name ="X24" Order = "18" Size = "8" />
            <Entry Name ="X25" Order = "19" Size = "8" />
            <Entry Name ="X26" Order = "1a" Size = "8" />
            <Entry Name ="X27" Order = "1b" Size = "8" />
            <Entry Name ="X28" Order = "1c" Size = "8" />
            <Entry Name ="fp"  Order = "1d" Size = "8" />
            <Entry Name ="lr"  Order = "1e" Size = "8" />
            <Entry Name ="sp"  Order = "1f" Size = "8" />
            <Entry Name ="pc"  Order = "20" Size = "8" />
            <Entry Name ="cpsr" Order = "21" Size = "8" />
            <Entry Name ="V0" Order = "22" Size = "16" />
            <Entry Name ="V1" Order = "23" Size = "16" />
            <Entry Name ="V2" Order = "24" Size = "16" />
            <Entry Name ="V3" Order = "25" Size = "16" />
            <Entry Name ="V4" Order = "26" Size = "16" />
            <Entry Name ="V5" Order = "27" Size = "16" />
            <Entry Name ="V6" Order = "28" Size = "16" />
            <Entry Name ="V7" Order = "29" Size = "16" />
            <Entry Name ="V8" Order = "2a" Size = "16" />
            <Entry Name ="V9" Order = "2b" Size = "16" />
            <Entry Name ="V10" Order = "2c" Size = "16" />
            <Entry Name ="V11" Order = "2d" Size = "16" />
            <Entry Name ="V12" Order = "2e" Size = "16" />
            <Entry Name ="V13" Order = "2f" Size = "16" />
            <Entry Name ="V14" Order = "30" Size = "16" />
            <Entry Name ="V15" Order = "31" Size = "16" />
            <Entry Name ="V16" Order = "32" Size = "16" />
            <Entry Name ="V17" Order = "33" Size = "16" />
            <Entry Name ="V18" Order = "34" Size = "16" />
            <Entry Name ="V19" Order = "35" Size = "16" />
            <Entry Name ="V20" Order = "36" Size = "16" />
            <Entry Name ="V21" Order = "37" Size = "16" />
            <Entry Name ="V22" Order = "38" Size = "16" />
            <Entry Name ="V23" Order = "39" Size = "16" />
            <Entry Name ="V24" Order = "3a" Size = "16" />
            <Entry Name ="V25" Order = "3b" Size = "16" />
            <Entry Name ="V26" Order = "3c" Size = "16" />
            <Entry Name ="V27" Order = "3d" Size = "16" />
            <Entry Name ="V28" Order = "3e" Size = "16" />
            <Entry Name ="V29" Order = "3f" Size = "16" />
            <Entry Name ="V30" Order = "3f" Size = "16" />
            <Entry Name ="V31" Order = "3f" Size = "16" />
            <Entry Name ="fpsr" Order = "40" Size = "4" />
            <Entry Name ="fpcr" Order = "41" Size = "4" />
        </ExdiGdbServerRegisters>


        <!-- x64 GDB server core resgisters -->
        <ExdiGdbServerRegisters Architecture = "X64" FeatureNameSupported = "sys" SystemRegistersStart = "18" SystemRegistersEnd = "20" >
            <Entry Name ="rax" Order = "0" Size ="8" />
            <Entry Name ="rbx" Order = "1" Size ="8" />
            <Entry Name ="rcx" Order = "2" Size ="8" />
            <Entry Name ="rdx" Order = "3" Size ="8" />
            <Entry Name ="rsi" Order = "4" Size ="8" />
            <Entry Name ="rdi" Order = "5" Size ="8" />
            <Entry Name ="rbp" Order = "6" Size ="8" />
            <Entry Name ="rsp" Order = "7" Size ="8" />
            <Entry Name ="r8"  Order = "8" Size ="8" />
            <Entry Name ="r9"  Order = "9" Size ="8" />
            <Entry Name ="r10" Order = "a" Size ="8" />
            <Entry Name ="r11" Order = "b" Size ="8" />
            <Entry Name ="r12" Order = "c" Size ="8" />
            <Entry Name ="r13" Order = "d" Size ="8" />
            <Entry Name ="r14" Order = "e" Size ="8" />
            <Entry Name ="r15" Order = "f" Size ="8" />
            <Entry Name ="rip" Order = "10" Size ="8" />
            <!-- <flags id="x64_eflags" size="4">
                <field name="" start="22" end="31"/>
                <field name="ID" start="21" end="21"/>
                <field name="VIP" start="20" end="20"/>
                <field name="VIF" start="19" end="19"/>
                <field name="AC" start="18" end="18"/>
                <field name="VM" start="17" end="17"/>
                <field name="RF" start="16" end="16"/>
                <field name="" start="15" end="15"/>
                <field name="NT" start="14" end="14"/>
                <field name="IOPL" start="12" end="13"/>
                <field name="OF" start="11" end="11"/>
                <field name="DF" start="10" end="10"/>
                <field name="IF" start="9" end="9"/>
                <field name="TF" start="8" end="8"/>
                <field name="SF" start="7" end="7"/>
                <field name="ZF" start="6" end="6"/>
                <field name="" start="5" end="5"/>
                <field name="AF" start="4" end="4"/>
                <field name="" start="3" end="3"/>
                <field name="PF" start="2" end="2"/>
                <field name="" start="1" end="1"/>
                <field name="CF" start="0" end="0"/>
            </flags> -->
            <Entry Name ="eflags" Order = "11" Size ="4" />

            <!-- Segment registers -->
            <Entry Name ="cs" Order = "12" Size ="4" />
            <Entry Name ="ss" Order = "13" Size ="4" />
            <Entry Name ="ds" Order = "14" Size ="4" />
            <Entry Name ="es" Order = "15" Size ="4" />
            <Entry Name ="fs" Order = "16" Size ="4" />
            <Entry Name ="gs" Order = "17" Size ="4" />

            <!-- Segment descriptor caches and TLS base MSRs -->
            <!--Entry Name ="cs_base" Order = "18" Size="8"/
            <Entry Name ="ss_base" Order = "18" Size ="8" />
            <Entry Name ="ds_base" Order = "19" Size ="8" />
            <Entry Name ="es_base" Order = "1a" Size ="8" /> -->
            <Entry Name ="fs_base" Order = "18" Size ="8" />
            <Entry Name ="gs_base" Order = "19" Size ="8" />
            <Entry Name ="k_gs_base" Order = "1a" Size ="8" />

            <!-- Control registers -->
            <!-- the cr0 register format fields:
            <flags id="x64_cr0" size="8">
            <field name="PG" start="31" end="31"/>
            <field name="CD" start="30" end="30"/>
            <field name="NW" start="29" end="29"/>
            <field name="AM" start="18" end="18"/>
            <field name="WP" start="16" end="16"/>
            <field name="NE" start="5" end="5"/>
            <field name="ET" start="4" end="4"/>
            <field name="TS" start="3" end="3"/>
            <field name="EM" start="2" end="2"/>
            <field name="MP" start="1" end="1"/>
            <field name="PE" start="0" end="0"/>
            </flags> -->
            <Entry Name ="cr0" Order = "1b" Size ="8" />
            <Entry Name ="cr2" Order = "1c" Size ="8" />

            <!-- the cr3 register format fields:
            <flags id="x64_cr3" size="8">
                <field name="PDBR" start="12" end="63"/>
                <field name="PCID" start="0" end="11"/>
            </flags> -->
            <Entry Name ="cr3" Order = "1d" Size ="8" />

            <!-- the cr4 register format fields:
            <flags id="x64_cr4" size="8">
                <field name="PKE" start="22" end="22"/>
                <field name="SMAP" start="21" end="21"/>
                <field name="SMEP" start="20" end="20"/>
                <field name="OSXSAVE" start="18" end="18"/>
                <field name="PCIDE" start="17" end="17"/>
                <field name="FSGSBASE" start="16" end="16"/>
                <field name="SMXE" start="14" end="14"/>
                <field name="VMXE" start="13" end="13"/>
                <field name="LA57" start="12" end="12"/>
                <field name="UMIP" start="11" end="11"/>
                <field name="OSXMMEXCPT" start="10" end="10"/>
                <field name="OSFXSR" start="9" end="9"/>
                <field name="PCE" start="8" end="8"/>
                <field name="PGE" start="7" end="7"/>
                <field name="MCE" start="6" end="6"/>
                <field name="PAE" start="5" end="5"/>
                <field name="PSE" start="4" end="4"/>
                <field name="DE" start="3" end="3"/>
                <field name="TSD" start="2" end="2"/>
                <field name="PVI" start="1" end="1"/>
                <field name="VME" start="0" end="0"/>
            </flags> -->
            <Entry Name ="cr4" Order = "1e" Size ="8" />
            <Entry Name ="cr8" Order = "1f" Size ="8" />

            <!-- the efer register format fields:
            <flags id="x64_efer" size="8">
            <field name="TCE" start="15" end="15"/>
            <field name="FFXSR" start="14" end="14"/>
            <field name="LMSLE" start="13" end="13"/>
            <field name="SVME" start="12" end="12"/>
            <field name="NXE" start="11" end="11"/>
            <field name="LMA" start="10" end="10"/>
            <field name="LME" start="8" end="8"/>
            <field name="SCE" start="0" end="0"/>
            </flags> -->
            <Entry Name ="efer" Order = "20" Size ="8"/>

            <!-- x87 FPU -->
            <Entry Name ="st0" Order = "21" Size ="10" />
            <Entry Name ="st1" Order = "22" Size ="10" />
            <Entry Name ="st2" Order = "23" Size ="10" />
            <Entry Name ="st3" Order = "24" Size ="10" />
            <Entry Name ="st4" Order = "25" Size ="10" />
            <Entry Name ="st5" Order = "26" Size ="10" />
            <Entry Name ="st6" Order = "27" Size ="10" />
            <Entry Name ="st7" Order = "28" Size ="10" />
            <Entry Name ="fctrl" Order = "29" Size ="4" />
            <Entry Name ="fstat" Order = "2a" Size ="4" />
            <Entry Name ="ftag"  Order = "2b" Size ="4" />
            <Entry Name ="fiseg" Order = "2c" Size ="4" />
            <Entry Name ="fioff" Order = "2d" Size ="4" />
            <Entry Name ="foseg" Order = "2e" Size ="4" />
            <Entry Name ="fooff" Order = "2f" Size ="4" />
            <Entry Name ="fop" Order = "30" Size ="4" />
            <Entry Name ="xmm0" Order = "31" Size ="16"  />
            <Entry Name ="xmm1" Order = "32" Size ="16"  />
            <Entry Name ="xmm2" Order = "33" Size ="16"  />
            <Entry Name ="xmm3" Order = "34" Size ="16"  />
            <Entry Name ="xmm4" Order = "35" Size ="16"  />
            <Entry Name ="xmm5" Order = "36" Size ="16"  />
            <Entry Name ="xmm6" Order = "37" Size ="16"  />
            <Entry Name ="xmm7" Order = "38" Size ="16"  />
            <Entry Name ="xmm8" Order = "39" Size ="16"  />
            <Entry Name ="xmm9" Order = "3a" Size ="16"  />
            <Entry Name ="xmm10" Order = "3b" Size ="16"  />
            <Entry Name ="xmm11" Order = "3c" Size ="16"  />
            <Entry Name ="xmm12" Order = "3d" Size ="16"  />
            <Entry Name ="xmm13" Order = "3e" Size ="16"  />
            <Entry Name ="xmm14" Order = "3f" Size ="16"  />
            <Entry Name ="xmm15" Order = "40" Size ="16"  />
            
            <!-- the mxcsr register format fields:
            <flags id="x64_mxcsr" size="4">
                <field name="IE" start="0" end="0"/>
                <field name="DE" start="1" end="1"/>
                <field name="ZE" start="2" end="2"/>
                <field name="OE" start="3" end="3"/>
                <field name="UE" start="4" end="4"/>
                <field name="PE" start="5" end="5"/>
                <field name="DAZ" start="6" end="6"/>
                <field name="IM" start="7" end="7"/>
                <field name="DM" start="8" end="8"/>
                <field name="ZM" start="9" end="9"/>
                <field name="OM" start="10" end="10"/>
                <field name="UM" start="11" end="11"/>
                <field name="PM" start="12" end="12"/>
                <field name="FZ" start="15" end="15"/>
            </flags> -->
            <Entry Name ="mxcsr" Order = "41" Size ="4" />

        </ExdiGdbServerRegisters>
    </ExdiGdbServerConfigData>
    </ExdiTarget>
    </ExdiTargets>
</ExdiTargets>

範例 EXDI PowerShell 腳本

此範例 PowerShell 腳本會安裝 EXDI,然後啟動調試程式。 Start-ExdiDebugger.ps1 腳本會視需要安裝ExdiGdbSrv.dll、設定 xml 配置檔、檢查是否執行dllhost.exe進程,以及啟動調試程式以聯機到已執行中的 gdb 伺服器硬體偵錯目標。

搭配WinDBg使用使用者介面時,已安裝ExdiGdbSrv.dll,而且此腳本不相關。 如需使用內建使用者介面的詳細資訊,請參閱 設定 EXDI 調試程式傳輸

這是呼叫啟動腳本的範例。

PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64

您也可以視需要指定建置的檔案。

PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

Start-ExdiDebugger.ps1 具有下列設定選項。

參數 描述
ExdiTarget 要連線的目標類型。 這會對應至設定 xml 檔案中的特定區段
HostName 載入 gdb 伺服器工作階段之電腦的 IP 位址或主機名稱(預設為 “LocalHost” )
GdbPort gdb 伺服器正在接聽的埠。
架構 硬體偵錯目標的架構(此參數也表示 xml 設定檔中的 ArchitectureFamily 參數)
ExdiDropPath ExdiGdbSrv.dll、exdiConfigData.xml和systemregisters.xml檔案的位置。 只有在未安裝ExdiGdbSrv.dll或安裝不正確時,才會複製這些複本。
ExtraDebuggerArgs 在調試程式命令行上傳遞的額外自變數
PreNTAppDebugging 將啟發學習型ScanSize 的值從 0xfffe (最適合 NT) 變更為 0xffe (適用於預先 NT 應用程式)
DontTryDllHostCleanup 檢查dllhost.exe中現有執行中ExdiGdbSrv.dll實例需要提高許可權。 提供此參數可讓腳本在沒有提高許可權的情況下執行(雖然調試程式可能無法正常運作)。

若要啟用要顯示的封包,請將displayCommPackets的值設定為 yes。

    [pscustomobject]@{ Path = 'displayCommPackets'                                  ; value = "yes" } 
.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

如需更多設定選項,請參閱程式代碼批注。

<#
.Synopsis
    Installs and launches exdi debugger (automating xml file editing)

.Description
    This script will install ExdiGdbSrv.dll if required, configure the xml settings
    files, check for running dllhost.exe processes, and launch the debugger to connect to
    an already running gdb server hardware debugging target.

.Parameter ExdiTarget
    Type of target to connect to. This corresponds to a specific section in the settings xml file

.Parameter HostName
    IP address or hostname of the computer hosting the gdb server session (defaults to "LocalHost")

.Parameter GdbPort
    Port that the gdb server is listening on.

.Parameter Architecture
    Architecture of the hardware debugging target (this parameter also implies the ArchitectureFamily
    parameter in the xml settings file)

.Parameter ExdiDropPath
    Location of the ExdiGdbSrv.dll, exdiConfigData.xml, and systemregisters.xml files. These will
    only be copied if ExdiGdbSrv.dll is not installed or is installed incorrectly.

.Parameter ExtraDebuggerArgs
    Extra arguments to pass on the debugger command line

.Parameter PreNTAppDebugging
    Changes the value of the heuristicScanSize from 0xfffe (best for NT) to 0xffe (for pre-NT Apps)

.Parameter DontTryDllHostCleanup
    Checking for existing running instances of ExdiGdbSrv.dll in dllhost.exe requires elevation.
    Providing this switch will allow the script to run without elevation (although the debugger may not
    function correctly).

.Example
    >---------------- (first run) ------------<
    .\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

.Example
    PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64
#>

[CmdletBinding()]
param
(
    [ValidateSet("QEMU")]
    [string]
    $ExdiTarget = "QEMU",

    [string]
    $HostName = "LocalHost",

    [Parameter(Mandatory=$true)]
    [Int]
    $GdbPort,

    [Parameter(Mandatory=$true)]
    [string]
    [ValidateSet("x86", "x64", "arm64")]
    $Architecture,

    [string]
    $ExdiDropPath,

    [string]
    $DebuggerPath,

    [string[]]
    $ExtraDebuggerArgs = @(),

    [switch]
    $PreNTAppDebugging,

    [switch]
    $DontTryDllHostCleanup
)

$ErrorActionPreference = "Stop"

#region Functions

Function Test-Admin
{
    ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
}

Function Find-PathToWindbgX
{
    $InternalWindbgXPath = "$env:LOCALAPPDATA\DBG\UI\WindbgX.exe"
    $ExternalWindbgXPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\WinDbgX.exe"

    if (Test-Path $InternalWindbgXPath -PathType Leaf)
    {
        return $InternalWindbgXPath
    }
    elseif (Test-Path $ExternalWindbgXPath -PathType Leaf)
    {
        return $ExternalWindbgXPath
    }
}

Function Test-ParameterValidation
{
    $CommandName = $PSCmdlet.MyInvocation.InvocationName
    $ParameterList = (Get-Command -Name $CommandName).Parameters

    foreach ($Parameter in $ParameterList) {
        Get-Variable -Name $Parameter.Values.Name -ErrorAction SilentlyContinue | Out-String | Write-Verbose
    }

    if (-not $DebuggerPath)
    {
        throw "WindbgX is not installed"
    }
    elseif (-not (Test-Path $DebuggerPath -PathType Leaf))
    {
        throw "DebuggerPath param ($DebuggerPath) does not point to a debugger."
    }

    # Searching for loaded instances of ExdiGdbSrv.dll in dllhost.exe requires elevation
    if (-not $DontTryDllHostCleanup -and
        -not $(Test-Admin))
    {
        throw "Searching for loaded instances of ExdiGdbSrv.dll in dllhost.exe requires elevation. Run with the -DontTryDllHostCleanup parameter to skip this check (debugger session init may fail)."
    }
}

Function Get-ExdiInstallPath
{
    Get-ItemPropertyValue -Path "Registry::HKEY_CLASSES_ROOT\CLSID\{29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014}\InProcServer32" -Name "(default)" -ErrorAction SilentlyContinue
}

Function Test-ExdiServerInstalled
{
    # Check registration of exdi server class
    if ($(Get-ExdiInstallPath) -ne $null -and $(Test-Path "$(Get-ExdiInstallPath)"))
    {
        Write-Verbose "Exdi server is installed. Checking installation..."
        $ExdiInstallDir = [System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath))
        if (-not (Test-Path $ExdiInstallDir))
        {
            Write-Host "Currently Registered exdi server does not exist. Reinstalling..."
            return $false
        }
        elseif (-not ((Test-Path "$ExdiInstallDir\exdiConfigData.xml") -and (Test-Path "$ExdiInstallDir\systemregisters.xml")))
        {
            Write-Host "Currently Registered exdi server does not have required xml settings files. Reinstalling..."
            return $false
        }
        else
        {
            Write-Verbose "Exdi server is insalled correctly. Skipping installation..."
            return $true
        }
    }
    else
    {
        Write-Host "Exdi server is not installed. Installing..."
        return $false
    }
}

Function Install-ExdiServer
{
    [CmdletBinding()]
    param
    (
        [string] $InstallFrom,
        [string] $InstallTo
    )
    
    if (-not $(Test-Admin))
    {
        throw "Script needs to be run as an Admin to install exdi software."
    }

    New-Item -ItemType Directory $InstallTo -ErrorAction SilentlyContinue | Write-Verbose
    Copy-Item -Path "$InstallFrom\ExdiGdbSrv.dll" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    Copy-Item -Path "$InstallFrom\exdiConfigData.xml" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    Copy-Item -Path "$InstallFrom\systemregisters.xml" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    regsvr32 /s "$InstallTo\ExdiGdbSrv.dll"

    if ($(Get-ExdiInstallPath) -eq $null)
    {
        throw "Unable to install exdi server"
    }
}

Function Edit-ExdiConfigFile
{
    [CmdletBinding()]
    param
    (
        [string] $ExdiFilePath,
        [string] $ExdiTargetType,
        [PSCustomObject[]] $XmlSettingPathValueList
    )
    
    # Edit exdiConfigData.xml
    [xml]$exdiConfigXml = Get-Content "$ExdiFilePath"

    # Set current target
    $exdiConfigXml.ExdiTargets.CurrentTarget = $ExdiTarget

    # set HostNameAndPort
    $ExdiTargetXmlNode = $exdiConfigXml.SelectSingleNode("//ExdiTargets/ExdiTarget[@Name='$ExdiTarget']/ExdiGdbServerConfigData")

    foreach ($XmlSettingPathValue in $XmlSettingPathValueList)
    {
        Write-Verbose "Processing $XmlSettingPathValue"
        if ($XmlSettingPathValue.Value -eq $null)
        {
            continue
        }

        $PathParts = $XmlSettingPathValue.Path.Split(".")
        $curNode = $ExdiTargetXmlNode
        if ($PathParts.Count -gt 1)
        {
            foreach ($PathPart in $PathParts[0..($PathParts.Count-2)])
            {
                Write-Verbose $PathPart
                $curNode = $curNode.($PathPart)
            }
        }
        $curNode.($PathParts[-1]) = $XmlSettingPathValue.Value
    }

    $exdiConfigXml.Save("$ExdiFilePath")
}

Function Stop-ExdiContainingDllHosts
{
    $DllHostPids = Get-Process dllhost | ForEach-Object { $_.Id }
    foreach ($DllHostPid in $DllHostPids)
    {
        $DllHostExdiDlls = Get-Process -Id $DllHostPid -Module | Where-Object { $_.FileName -like "*ExdiGdbSrv.dll" }
        if ($DllHostExdiDlls.Count -ne 0)
        {
            Write-Verbose "Killing dllhost.exe with pid $DllHostPid (Contained instance of ExdiGdbSrv.dll)"
            Stop-Process -Id $DllHostPid -Force
        }
    }
}

#endregion

#region Script

# Apply defaults for $DebuggerPath before Parameter validation
if (-not $DebuggerPath)
{
    $DebuggerPath = Find-PathToWindbgX
}

Test-ParameterValidation

# look clean up dllhost.exe early since it can hold a lock on files which
# need to be overwritten
if (-not $DontTryDllHostCleanup)
{
    Stop-ExdiContainingDllHosts
}

if (-not $(Test-ExdiServerInstalled))
{
    if (-not $ExdiDropPath)
    {
        throw "ExdiServer is not installed and -ExdiDropPath is not valid"
    }

    $ExdiInstallDir = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($DebuggerPath))" -ChildPath "exdi"
    Install-ExdiServer -InstallFrom "$ExdiDropPath" -InstallTo "$ExdiInstallDir"
}

$SystemRegistersFilepath = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath)))" -ChildPath "systemregisters.xml"
$ExdiConfigFilepath      = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath)))" -ChildPath "exdiConfigData.xml"

# Calculate implied parameters
$HeuristicScanSize = if ($PreNTAppDebugging) { "0xffe" } else { "0xfffe" }
$ArchitectureFamily = switch($Architecture)
{
    x64   { "ProcessorFamilyx64" }
    x86   { "ProcessorFamilyx86" }
    arm64 { "ProcessorFamilyARM64" }
}

# Path is evaluated relative to the relevant ExdiTarget's ExdiGdbServerConfigData node in the xml schema
$SettingsToChange = @(
    [pscustomobject]@{ Path = 'GdbServerConnectionParameters.Value.HostNameAndPort' ; Value = "${HostName}:$GdbPort" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.targetArchitecture'          ; Value = "$Architecture" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.targetFamily'                ; Value = "$ArchitectureFamily" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.heuristicScanSize'           ; Value = "$HeuristicScanSize" },
    [pscustomobject]@{ Path = 'displayCommPackets'                                  ; value = "no" }
)
Edit-ExdiConfigFile -ExdiFilePath "$ExdiConfigFilepath" -ExdiTargetType "$ExdiTarget" -XmlSettingPathValueList $SettingsToChange

# Set env vars for debugger
[System.Environment]::SetEnvironmentVariable('EXDI_GDBSRV_XML_CONFIG_FILE',"$ExdiConfigFilepath")
[System.Environment]::SetEnvironmentVariable('EXDI_SYSTEM_REGISTERS_MAP_XML_FILE',"$SystemRegistersFilepath")

$DebuggerArgs = @("-v", "-kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,DataBreaks=Exdi")
Write-Verbose "DebuggerPath = $DebuggerPath"
Start-Process -FilePath "$DebuggerPath" -ArgumentList ($DebuggerArgs + $ExtraDebuggerArgs)

#endregion

另請參閱

設定 EXDI 調試程式傳輸

使用 EXDI 設定 QEMU 內核模式偵錯

.exdicmd (EXDI 命令)

自動設定 KDNET 網路核心偵錯