卡掛死寄存器現(xiàn)場(chǎng)抓取與WinDbg調(diào)試實(shí)戰(zhàn))
簡(jiǎn)介icedump 6.026 與 nticedump 1.14 是一套面向 Windows 平臺(tái)的內(nèi)存分析與內(nèi)核調(diào)試工具適用于逆向工程、驅(qū)動(dòng)開(kāi)發(fā)、系統(tǒng)崩潰定位及內(nèi)核研究。壓縮包共 410 個(gè)文件包含 90 個(gè) .asm 匯編源碼、152 個(gè) .inc 頭文件、36 個(gè) .exe 可執(zhí)行程序以及 DLL、LIB、Makefile、TXT 說(shuō)明文檔等既可直接運(yùn)行調(diào)試也可從源碼級(jí)理解內(nèi)存轉(zhuǎn)儲(chǔ)、模塊枚舉、線程信息與堆分配的實(shí)現(xiàn)細(xì)節(jié)。整包僅 2.62MB輕量且結(jié)構(gòu)清晰已有 164 人學(xué)習(xí)/下載。價(jià)值在于可用性高cmd_trace、cmd_step、cmd_protect 等命令模塊提供功能示例history.txt 展示版本演進(jìn)file_id.diz 給出快速說(shuō)明針對(duì) Windows NT 與 9x 平臺(tái)的專用配置以及 common 目錄下的公共組件能為二次開(kāi)發(fā)提供基礎(chǔ)尤其適合希望深入 Windows 內(nèi)核調(diào)試、自行構(gòu)建調(diào)試工具鏈的讀者。1. 網(wǎng)卡掛死卻找不到寄存器現(xiàn)場(chǎng)icedump 與 nticedump 能兜住什么做內(nèi)核驅(qū)動(dòng)的人多半遇到過(guò)這種場(chǎng)面業(yè)務(wù)側(cè)報(bào)“網(wǎng)卡不通”可鏈路是 up 的交換機(jī)端口也正常驅(qū)動(dòng)日志里沒(méi)有任何錯(cuò)誤tcpdump 抓包甚至還能看到零星的收發(fā)。但吞吐就是突然歸零過(guò)一會(huì)兒又自己恢復(fù)。這種故障最吊詭的地方在于問(wèn)題根本不在協(xié)議棧的數(shù)據(jù)路徑里而在 DMA 環(huán)是否還在推進(jìn)、描述符狀態(tài)位是否被置位這些硬件細(xì)節(jié)上。而協(xié)議層工具看不到這些細(xì)節(jié)。icedump 這類工具就是把這一層現(xiàn)場(chǎng)撈出來(lái)的。它通過(guò) NDIS 鉤子讀取網(wǎng)卡寄存器、收發(fā)描述符和 DMA 隊(duì)列狀態(tài)在系統(tǒng)崩潰或網(wǎng)卡異常時(shí)生成一份可以直接分析的 dump 文件。這份壓縮包里同時(shí)打包了 icedump 6.026 和 nticedump 1.14 兩個(gè)版本分支前者面向現(xiàn)在的 Windows 調(diào)試鏈路后者面向 NT 系列的老調(diào)試器。適合內(nèi)核驅(qū)動(dòng)開(kāi)發(fā)者、底層網(wǎng)絡(luò)運(yùn)維和做系統(tǒng)故障定位的工程師。拿到它之后你至少能把“網(wǎng)卡為什么不動(dòng)”從玄學(xué)變成可查證的事實(shí)。2. 包結(jié)構(gòu)與調(diào)試原理從 NDIS 鉤子到 DMA 描述符的距離2.1 壓縮包里裝了什么兩代工具的邊界這份資源的標(biāo)題寫(xiě)得很直白icedump 6.026 和 nticedump 1.14.zip。拆開(kāi)之后兩類文件要分開(kāi)看待——一類是工具本體另一類是配套的解析庫(kù)和腳本。常見(jiàn)打包方式是 .sys 驅(qū)動(dòng)文件、.dll 輔助庫(kù)、.exe 命令行工具和若干 .bat / .ini 腳本混在一起。新手最容易犯的錯(cuò)是把所有文件都當(dāng)成驅(qū)動(dòng)去注冊(cè)其實(shí)真正需要加載到內(nèi)核里的只有 .sys 驅(qū)動(dòng)文件其余是解析和觸發(fā)采集用的外圍程序。文件類型常見(jiàn)文件名特征作用驅(qū)動(dòng)程序.sys掛在 NDIS 層負(fù)責(zé)打開(kāi)寄存器轉(zhuǎn)儲(chǔ)入口輔助庫(kù).dll提供寄存器偏移定義和解析函數(shù)命令行工具.exe觸發(fā)采集、停止采集、生成 dump 文件配置腳本.bat / .ini自動(dòng)化加載驅(qū)動(dòng)并設(shè)置采集參數(shù)6.026 和 1.14 的分界不完全是時(shí)間先后而是調(diào)試鏈路不同。6.026 這個(gè)版本對(duì)較新的網(wǎng)卡驅(qū)動(dòng)適配更好能通過(guò)改進(jìn)后的 NDIS 接口拿到更多內(nèi)部狀態(tài)nticedump 1.14 則保留了更接近 NT 時(shí)代調(diào)試器的用法。實(shí)際使用時(shí)選擇依據(jù)是目標(biāo)機(jī)上跑的網(wǎng)卡驅(qū)動(dòng)版本而不是 Windows 版本。老驅(qū)動(dòng)強(qiáng)行配新工具寄存器偏移對(duì)不上dump 出來(lái)反而更難讀。2.2 調(diào)試原理為什么工具能讀到網(wǎng)卡寄存器網(wǎng)卡的寄存器在硬件上通過(guò) PCIe BAR 映射到了系統(tǒng)的物理內(nèi)存地址空間。也就是說(shuō)只要工具以驅(qū)動(dòng)身份運(yùn)行就可以通過(guò)訪問(wèn)映射后的地址來(lái)讀取寄存器值不需要額外的硬件探針。icedump 做的就是在 NDIS 層插入一個(gè)鉤子在網(wǎng)卡驅(qū)動(dòng)處理收發(fā)請(qǐng)求的路徑上取得一組一致性的狀態(tài)快照。這個(gè)快照包含三塊內(nèi)容寄存器值、描述符狀態(tài)、隊(duì)列指針。DMA 環(huán)是理解這類 dump 的關(guān)鍵。網(wǎng)卡和主機(jī)之間共享一塊內(nèi)存區(qū)域主機(jī)端往環(huán)里放描述符描述符告訴網(wǎng)卡“下一個(gè)數(shù)據(jù)包放到哪里、長(zhǎng)度是多少”。環(huán)的推進(jìn)由 head 和 tail 兩個(gè)指針控制head 是軟件寫(xiě)入的位置tail 是網(wǎng)卡消費(fèi)的位置。正常工作時(shí)兩個(gè)指針持續(xù)交替前進(jìn)當(dāng)某一側(cè)的指針停住就說(shuō)明軟件和硬件之間出現(xiàn)了不一致。協(xié)議棧感覺(jué)不到這種停滯它只知道提交了描述符卻不知道硬件有沒(méi)有真正取走。dump 文件里最值得先看的就是 head 和 tail 的差距。如果兩者恒定不變說(shuō)明 DMA 環(huán)已經(jīng)停止推進(jìn)接下來(lái)去查描述符的狀態(tài)位基本就能定位是硬件停發(fā)還是驅(qū)動(dòng)沒(méi)有補(bǔ)充描述符。這類結(jié)構(gòu)化的現(xiàn)場(chǎng)只有在故障發(fā)生后立即抓取才有意義這也是這類工具和普通抓包工具定位完全不同之處。2.3 選型理由與邊界協(xié)議棧工具看不到的現(xiàn)場(chǎng)tcpdump、NetMon 這類工具工作在網(wǎng)絡(luò)協(xié)議層它們看到的包是已經(jīng)被網(wǎng)卡接收、驅(qū)動(dòng)處理完的成品。換句話說(shuō)當(dāng)數(shù)據(jù)通路斷在“網(wǎng)卡硬件到內(nèi)存”這一段時(shí)協(xié)議層工具抓到的只是失敗后的殘余現(xiàn)象甚至什么都抓不到。鏈路 up、驅(qū)動(dòng)無(wú)錯(cuò)、但吞吐歸零這種狀態(tài)下協(xié)議層日志往往是干凈的因?yàn)殄e(cuò)誤根本沒(méi)有被記錄。icedump 填的正是這個(gè)觀察空隙。它能回答的問(wèn)題是網(wǎng)卡是否還在工作、DMA 環(huán)停在哪個(gè)位置、描述符有沒(méi)有被硬件消費(fèi)。這比“丟了多少個(gè)包”更接近故障根源。但反過(guò)來(lái)它不負(fù)責(zé)回答“數(shù)據(jù)包內(nèi)容是什么”因?yàn)?dump 里保存的是寄存器狀態(tài)和描述符索引不是報(bào)文樣本。實(shí)際排障時(shí)先用 icedump 確認(rèn)硬件狀態(tài)再用協(xié)議抓包確認(rèn)表現(xiàn)兩者對(duì)照才完整。只拿其中一份下結(jié)論很容易被表面現(xiàn)象誤導(dǎo)。3. 跑通一次真實(shí)抓取WinDbg 下的加載、命令與解讀3.1 環(huán)境準(zhǔn)備測(cè)試簽名、雙機(jī)調(diào)試與符號(hào)路徑第一次上手這類工具最先遇到的不是抓取命令而是驅(qū)動(dòng)加載問(wèn)題。icedump 本質(zhì)上是一個(gè)內(nèi)核驅(qū)動(dòng)而這類調(diào)試工具的驅(qū)動(dòng)往往沒(méi)有能與當(dāng)前 Windows 版本完全匹配的正式簽名鏈。常見(jiàn)做法是先關(guān)閉 Secure Boot再打開(kāi) Windows 的測(cè)試簽名模式否則加載時(shí)會(huì)被直接拒絕。bcdedit /set testsigning on bcdedit /set {bootmgr} displaybootmenu yes shutdown /r /t 0第一句打開(kāi)測(cè)試簽名開(kāi)關(guān)讓系統(tǒng)允許加載未正式簽名的驅(qū)動(dòng)第二句讓重啟時(shí)顯示引導(dǎo)菜單萬(wàn)一起不來(lái)還有后悔藥第三句立即重啟。注意testsigning只在 Secure Boot 關(guān)閉時(shí)生效如果 BIOS 里開(kāi)著 Secure Boot這一步會(huì)白做。我實(shí)際踩過(guò)的坑是只執(zhí)行了第一句就重啟結(jié)果加載時(shí)照樣報(bào)簽名錯(cuò)誤回頭查才發(fā)現(xiàn) BIOS 里的 Secure Boot 沒(méi)關(guān)。雙機(jī)調(diào)試建議用網(wǎng)絡(luò)調(diào)試方式連目標(biāo)機(jī)。WinDbg 連接后設(shè)置符號(hào)路徑這一步不能省否則后續(xù)解析模塊時(shí)符號(hào)加載不全。.sympath srv*C:\Symbols*https://msdl.microsoft.com/download/symbols .reload.sympath是 WinDbg 里設(shè)置符號(hào)路徑的命令前面的srv*表示從微軟符號(hào)服務(wù)器下載本地路徑C:\Symbols用于緩存。.reload強(qiáng)制重新加載模塊符號(hào)。這里有個(gè)實(shí)操細(xì)節(jié)符號(hào)下載一次后緩存住后續(xù)離線也能用。如果現(xiàn)場(chǎng)機(jī)沒(méi)有外網(wǎng)訪問(wèn)權(quán)限可以先在有網(wǎng)的環(huán)境把符號(hào)緩存好再拷過(guò)去。3.2 加載驅(qū)動(dòng)模塊并初始化采集環(huán)境準(zhǔn)備好之后在 WinDbg 的命令行里加載 icedump 驅(qū)動(dòng)模塊。不同版本的擴(kuò)展命令前綴可能略有差異這里以最常見(jiàn)的命名方式演示。.load C:\tools\icedump\icedump.sys !ice.init.load將驅(qū)動(dòng)模塊加載進(jìn)內(nèi)核調(diào)試會(huì)話路徑必須是目標(biāo)機(jī)可訪問(wèn)的完整路徑。!ice.init是初始化命令作用是匹配當(dāng)前網(wǎng)卡設(shè)備并建立 BAR 映射。初始化成功會(huì)返回設(shè)備列表列出識(shí)別到的網(wǎng)卡類型和寄存器基地址。如果返回 0x0 或者提示未找到設(shè)備先別急著懷疑網(wǎng)卡大概率是 BAR 基地址沒(méi)有被正確解析這個(gè)問(wèn)題在第 4 章專門(mén)說(shuō)。初始化完成后建議順手驗(yàn)證一下設(shè)備是否真的被掛住。執(zhí)行一次簡(jiǎn)單的狀態(tài)讀取確認(rèn)返回的基地址落在合理范圍內(nèi)。這一步能過(guò)濾掉大半后續(xù) dump 全 0 的問(wèn)題。我一般會(huì)在.load之后先做一次初始化再跑一次采集等到真正需要分析時(shí)再打開(kāi)完整 dump避免在故障現(xiàn)場(chǎng)浪費(fèi)時(shí)間做無(wú)意義的調(diào)試。3.3 抓取寄存器現(xiàn)場(chǎng)并保存 dump故障現(xiàn)場(chǎng)不穩(wěn)定抓取動(dòng)作要快。如果系統(tǒng)還有響應(yīng)可以直接觸發(fā)采集并生成內(nèi)核轉(zhuǎn)儲(chǔ)。!ice.capture .dump /ma C:\crash\fault.dmp!ice.capture是觸發(fā)采集的命令它會(huì)把當(dāng)前網(wǎng)卡的寄存器、描述符環(huán)和隊(duì)列狀態(tài)寫(xiě)入調(diào)試器內(nèi)存。.dump /ma是將調(diào)試會(huì)話里的完整內(nèi)存信息保存成轉(zhuǎn)儲(chǔ)文件/ma參數(shù)表示包含完整內(nèi)存內(nèi)容這樣事后分析時(shí)還能重新讀取寄存器映射區(qū)域。文件保存路徑建議用絕對(duì)路徑避免調(diào)試器默認(rèn)路徑不明確導(dǎo)致找不到文件。如果系統(tǒng)已經(jīng)完全死住就不能依賴目標(biāo)機(jī)執(zhí)行命令需要在宿主機(jī)上執(zhí)行.dump。這種離線場(chǎng)景下采集動(dòng)作依賴預(yù)先配置好的自動(dòng)觸發(fā)。實(shí)際操作中我會(huì)在調(diào)試器里設(shè)置條件斷點(diǎn)當(dāng)檢測(cè)到丟包率或吞吐異常時(shí)自動(dòng)執(zhí)行!ice.capture和.dump不等人工介入。故障發(fā)生到人工反應(yīng)過(guò)來(lái)往往已經(jīng)過(guò)去幾十秒驅(qū)動(dòng)可能已經(jīng)執(zhí)行了重置流程現(xiàn)場(chǎng)早被沖洗掉了。3.4 讀 dump 的關(guān)鍵字段拿到 dump 之后優(yōu)先看幾個(gè)字段。下面這張表列的是我每次打開(kāi) dump 都會(huì)先掃一遍的項(xiàng)。字段含義異常判斷收發(fā)控制寄存器鏈路狀態(tài)、MAC 使能狀態(tài)使能位為 0說(shuō)明網(wǎng)卡已停止收發(fā)head/tail 指針DMA 環(huán)的寫(xiě)入位置和消費(fèi)位置兩者差距恒定不變說(shuō)明隊(duì)列停止推進(jìn)接收描述符狀態(tài)位描述符是否已被硬件填充完畢連續(xù)多個(gè)未置完成位說(shuō)明數(shù)據(jù)在硬件側(cè)積壓發(fā)送完成狀態(tài)發(fā)送描述符是否被硬件取走完成位為 0 且隊(duì)列滿說(shuō)明硬件未消費(fèi)最常見(jiàn)的一種異常模式是 head 和 tail 的差距恒定不變。比如 head 停在 0x3F0tail 停在 0x3E0只差 16 字節(jié)說(shuō)明最后一個(gè)描述符只填了一半DMA 引擎停在了這個(gè)位置。此時(shí)去看描述符狀態(tài)位如果完成位沒(méi)有置位基本可以確認(rèn)是硬件側(cè)停止消費(fèi)如果完成位已經(jīng)置位但 head 沒(méi)有前進(jìn)則需要懷疑驅(qū)動(dòng)側(cè)沒(méi)有及時(shí)補(bǔ)充描述符。這兩個(gè)方向決定了后續(xù)排查路徑完全不同。4. 避坑記錄簽名、基地址與 dump 數(shù)據(jù)的欺騙性4.1 加載藍(lán)屏或拒絕加載別先怪工具現(xiàn)象在 WinDbg 里執(zhí)行.load后目標(biāo)機(jī)直接藍(lán)屏或者彈出“無(wú)法驗(yàn)證驅(qū)動(dòng)簽名”的提示。第一次遇到時(shí)很容易覺(jué)得是工具包壞了或者版本不對(duì)。原因這類舊調(diào)試驅(qū)動(dòng)的簽名鏈大概率與當(dāng)前內(nèi)核版本不匹配。Secure Boot 開(kāi)啟時(shí)測(cè)試簽名不會(huì)生效加載動(dòng)作直接失敗即使關(guān)閉了 Secure Boot如果目標(biāo)系統(tǒng)沒(méi)有打開(kāi)testsigning同樣會(huì)被拒之門(mén)外。解決重啟進(jìn) BIOS 關(guān)閉 Secure Boot然后在管理員命令行里執(zhí)行bcdedit /set testsigning on并重啟。如果做完這兩步仍然藍(lán)屏再檢查 WinDbg 工具版本與目標(biāo)操作系統(tǒng)位寬是否一致——32 位工具在 64 位目標(biāo)機(jī)上加載內(nèi)核模塊崩潰概率極高。這條是血淚經(jīng)驗(yàn)別在沒(méi)關(guān) Secure Boot 的情況下開(kāi)測(cè)翻車概率很高。4.2 dump 里全是 0先懷疑基地址別懷疑網(wǎng)卡現(xiàn)象采集出來(lái)的寄存器區(qū)域幾乎全 0或者讀出的地址值高得離譜明顯不在設(shè)備映射范圍內(nèi)。第一次見(jiàn)到這種結(jié)果很容易誤判成“網(wǎng)卡徹底沒(méi)響應(yīng)”。原因!ice.init沒(méi)有正確解析到網(wǎng)卡 BAR 基地址工具讀取的是 PCI 配置空間里的空洞或者錯(cuò)誤偏移拿到自然都是一堆 0。這種情況在主板有多個(gè) PCIe 插槽、網(wǎng)卡被 BIOS 重新編號(hào)時(shí)尤其常見(jiàn)。解決先通過(guò)調(diào)試器的!pci命令或者進(jìn)入系統(tǒng)后用 lspci 工具拿到該網(wǎng)卡的實(shí)際 BAR 地址再在初始化階段手動(dòng)指定給 icedump。常見(jiàn)做法是在初始化命令后面追加 BAR 參數(shù)讓工具始終對(duì)準(zhǔn)映射后的內(nèi)存窗口而不是依賴自動(dòng)猜測(cè)。我實(shí)際遇到的全 0 dump十個(gè)里有八個(gè)是這個(gè)原因不是網(wǎng)卡真掛了。4.3 寄存器偏移對(duì)不上驅(qū)動(dòng)版本匹配問(wèn)題現(xiàn)象dump 能正常讀出來(lái)但寄存器值在語(yǔ)義上說(shuō)不通。比如收包計(jì)數(shù)器的數(shù)值遠(yuǎn)超硬件實(shí)際處理能力或者發(fā)送完成狀態(tài)位的判斷結(jié)果和驅(qū)動(dòng)日志互相矛盾。原因不同版本的網(wǎng)卡驅(qū)動(dòng)對(duì)寄存器偏移的解釋不完全一致icedump 在編譯時(shí)綁定了特定驅(qū)動(dòng)版本的寄存器定義。拿 6.026 這個(gè)較新的工具去配一個(gè)很老的網(wǎng)卡驅(qū)動(dòng)偏移錯(cuò)位是必然的。解決抓取之前先確認(rèn)目標(biāo)機(jī)上正在運(yùn)行的網(wǎng)卡驅(qū)動(dòng)版本再選擇匹配的 icedump 版本。這份壓縮包同時(shí)包含 6.026 和 nticedump 1.14就是為了覆蓋新老兩代驅(qū)動(dòng)場(chǎng)景。選擇標(biāo)準(zhǔn)是網(wǎng)卡驅(qū)動(dòng)版本而不是 Windows 版本。我曾在一臺(tái) Windows 10 機(jī)器上遇到過(guò)老驅(qū)動(dòng)配合新版工具讀出來(lái)的寄存器值明顯錯(cuò)位換成 nticedump 1.14 后一切正常。4.4 抓得太晚現(xiàn)場(chǎng)已經(jīng)被驅(qū)動(dòng)重置現(xiàn)象故障發(fā)生時(shí)沒(méi)有及時(shí)抓取事后補(bǔ)的 dump 看起來(lái)完全正常。寄存器狀態(tài)正常隊(duì)列指針也在合理區(qū)間什么問(wèn)題都看不出來(lái)。原因網(wǎng)卡驅(qū)動(dòng)在檢測(cè)到掉線或異常后會(huì)執(zhí)行重置流程重置完成后 DMA 環(huán)被重新初始化故障現(xiàn)場(chǎng)被沖洗掉了。抓取動(dòng)作越晚看到的越是“重置后的健康狀態(tài)”而不是“故障時(shí)的真實(shí)狀態(tài)”。解決把抓取動(dòng)作前置。在網(wǎng)卡丟包率或吞吐異常達(dá)到閾值時(shí)自動(dòng)觸發(fā)采集和轉(zhuǎn)儲(chǔ)而不是等人工發(fā)現(xiàn)再操作。實(shí)操中我會(huì)在調(diào)試器里掛一組條件觸發(fā)讓特征一出現(xiàn)就立即生成 dump。就像提前準(zhǔn)備了后悔藥故障發(fā)生時(shí)不用手忙腳亂去找命令。4.5 別把 dump 當(dāng)協(xié)議包分析現(xiàn)象拿到 dump 文件后試圖從中找出“哪個(gè)包丟了”“哪條 TCP 流斷了”這些協(xié)議層面的信息折騰半天發(fā)現(xiàn) dump 里根本沒(méi)有報(bào)文內(nèi)容。原因dump 記錄的是寄存器值、描述符狀態(tài)和隊(duì)列指針不是報(bào)文樣本。它能告訴你硬件卡在哪一步卻不能還原每一步里傳遞的具體數(shù)據(jù)內(nèi)容。把 dump 當(dāng)協(xié)議包分析是找錯(cuò)了工具。解決丟包追溯問(wèn)題要同時(shí)采集協(xié)議層日志。用 icedump 確認(rèn) DMA 環(huán)停住的位置和描述符狀態(tài)用 Wireshark 或 NetMon 確認(rèn)協(xié)議層顯示的丟包現(xiàn)象兩者對(duì)照才能還原完整鏈路。單看任何一份都是片面的尤其不能因?yàn)樵?dump 里沒(méi)看到某個(gè)數(shù)據(jù)包就下結(jié)論說(shuō)這個(gè)包沒(méi)有到達(dá)網(wǎng)卡。5. 驗(yàn)證抓取是否可信交叉核對(duì)與現(xiàn)場(chǎng)還原5.1 用計(jì)數(shù)器做交叉核對(duì)拿到一份看起來(lái)合理的 dump先別急著信。一個(gè)簡(jiǎn)單的驗(yàn)證方法是用計(jì)數(shù)器交叉核對(duì)把 dump 里的收發(fā)狀態(tài)字段與系統(tǒng)側(cè)的網(wǎng)卡計(jì)數(shù)器、中斷頻率放在一起對(duì)比。如果 dump 顯示 DMA 環(huán)停止推進(jìn)而系統(tǒng)側(cè)收包計(jì)數(shù)器還在持續(xù)增長(zhǎng)說(shuō)明抓取到的狀態(tài)和實(shí)際數(shù)據(jù)路徑不一致要么是采集時(shí)機(jī)不對(duì)要么是工具解析偏移有誤。反過(guò)來(lái)如果兩側(cè)都顯示停止這份 dump 的可信度就高很多。5.2 時(shí)間對(duì)齊協(xié)議日志如果故障現(xiàn)場(chǎng)同時(shí)有協(xié)議層抓包日志可以做時(shí)間對(duì)齊驗(yàn)證。比如 dump 顯示 head 停在某個(gè)描述符位置時(shí)對(duì)應(yīng)時(shí)間點(diǎn)的協(xié)議日志應(yīng)該能觀察到同一方向的吞吐驟降或中斷停止。時(shí)間戳對(duì)不上就要懷疑調(diào)試器時(shí)鐘與目標(biāo)機(jī)時(shí)鐘有沒(méi)有偏差這是雙機(jī)調(diào)試時(shí)很容易忽略的問(wèn)題。通常我會(huì)在采集前后各記錄一次調(diào)試器時(shí)間再和目標(biāo)機(jī)日志時(shí)間做差值校準(zhǔn)確保對(duì)齊不是靠肉眼猜。5.3 同一故障復(fù)現(xiàn)兩次驗(yàn)證關(guān)鍵字段最可信的驗(yàn)證方式是讓同一個(gè)故障條件再觸發(fā)一次重復(fù)采集。兩次 dump 的關(guān)鍵字段應(yīng)當(dāng)保持一致head 和 tail 停在相同或相鄰的位置描述符狀態(tài)位的組合模式不變。如果兩次抓取得到完全不同的停止位置說(shuō)明故障本身是隨機(jī)的或者采集過(guò)程干擾了故障現(xiàn)場(chǎng)。我一般會(huì)在同條件下連續(xù)復(fù)現(xiàn)三次前兩次確認(rèn)故障確定性第三次正式采集留作分析依據(jù)。從那以后我每次收到“網(wǎng)卡異?!钡膱?bào)障都強(qiáng)制先跑一遍 icedump 拿到寄存器現(xiàn)場(chǎng)再做協(xié)議層分析。寧可多花幾分鐘抓現(xiàn)場(chǎng)也不憑日志猜原因。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取