避免調試程式搜尋不需要的符號
上次更新:
- 2007年5月27日
您在偵錯驅動程式時抵達有趣的斷點,只在嘗試載入您不擁有之驅動程式的符號時,讓調試程序暫停很長一段時間,而且甚至對手邊偵錯工作並不重要。 這是怎麼一回事?
根據預設,調試程式會視需要載入符號。 (這稱為延後符號載入或延遲符號載入。) 調試程式會在執行呼叫顯示符號的命令時尋找符號。 如果您已設定在目前內容中無效的 watch 變數,例如目前堆疊框架中不存在的函式參數或局部變數,就會在斷點發生此情況,因為它們在內容變更時變成無效。 如果您只是輸入符號名稱或執行無效的調試程式命令,調試程式會開始尋找相符的符號,也可能會發生此情況。
為什麼這有時候需要這麼長的時間? 這取決於符號名稱是限定還是不合格的。 限定符號名稱前面加上包含符號的模組名稱,例如 myModule!myVar。 不合格的符號名稱未指定模組名稱,例如 myOtherVar。
在限定名稱的情況下,調試程式會在指定的模塊中尋找符號,如果模組尚未載入,則載入模組 (假設模組存在且包含符號) 。 這會非常快速地發生。
在未限定名稱的情況下,調試程式不會「知道」哪一個模組包含符號,因此必須查看所有模組。 調試程式會先檢查所有已載入的模組是否有符號,如果它不符合任何載入模組中的符號,調試程式會載入所有卸除的模組,從下游存放區開始,並以符號伺服器結束,以繼續搜尋。 很明顯地,這可能需要很多時間。
如何防止自動載入不合格的符號
SYMOPT_NO_UNQUALIFIED_LOADS選項會停用或啟用調試程式在搜尋未限定符號時自動載入模組。 設定SYMOPT_NO_UNQUALIFIED_LOADS且調試程序嘗試比對不合格的符號時,只會搜尋已經載入的模組,並在無法比對符號時停止搜尋,而不是載入卸除的模組以繼續搜尋。 此選項不會影響搜尋限定名稱。
默認 會關閉SYMOPT_NO_UNQUALIFIED_LOADS。 若要啟用此選項,請使用 -snul 命令行選項,或在調試程序執行時,分別使用 .symopt+0x100 或 .symopt-0x100 來開啟或關閉選項。
若要查看 SYMOPT_NO_UNQUALIFIED_LOADS的效果,請嘗試此實驗:
- 使用 -n 命令行選項啟動雜訊符號載入 (SYMOPT_DEBUG) ,或者,如果調試程式已經執行,請使用 .symopt+0x80000000 或 !sym 雜訊調試程式延伸模組命令。 SYMOPT_DEBUG 會指示調試程序顯示其搜尋符號的相關信息,例如載入每個模組的名稱,如果調試程式找不到檔案,則會顯示錯誤訊息。
- 指示調試程式評估不存在的符號 (例如,輸入 ?asdasdasd) 。 調試程序應該會在搜尋不存在的符號時回報許多錯誤。
- 使用 .symopt+0x100 啟用SYMOPT_NO_UNQUALIFIED_LOADS。
- 重複步驟 2。 調試程式應該只搜尋不存在符號的載入模組,而且應該更快完成工作。
- 若要停用 SYMOPT_DEBUG,請使用 .symopt-0x80000000 或 !sym quiet 調試程序擴充命令。
有數個選項可用來控制調試程式載入和使用符號的方式。 如需符號選項的完整清單及其使用方式,請參閱 Windows 偵錯工具所提供的在線檔中的。 最新版的 Windows 偵錯工具套件可從 Web 免費下載,或者您可以從 Windows DDK、Platform SDK 或客戶支援診斷 CD 安裝套件。
您應該怎麼做?
- 若要加速符號搜尋,請盡可能在斷點和調試程式命令中使用限定名稱。 如果您想要從已知模組看到符號,請使用模組名稱來限定它;如果您不知道符號的位置,請使用不合格的名稱。 針對局部變數和函式自變數,請使用 $ 作為模組名稱 (例如 $!MyVar) 。
- 若要診斷符號載入速度緩慢的原因,請使用 -n 命令行選項啟動雜訊符號載入 (SYMOPT_DEBUG) ,或者,如果調試程式已經執行,請使用 .symopt+0x80000000 或 !sym noisy 調試程序擴充命令。
- 若要防止調試程式在卸除的模組中搜尋符號,請使用 -snul 命令行選項啟動SYMOPT_NO_UNQUALIFIED_LOADS,或者,如果調試程式已在執行中,請使用 .symopt+0x100。
- 若要明確載入偵錯會話所需的模組,請使用 .reload 或 ld 之類的調試程式命令。