出版時間:2008-6 出版社:電子工業(yè)出版社 作者:張銀奎 頁數(shù):1006
Tag標(biāo)簽:無
內(nèi)容概要
圍繞如何實(shí)現(xiàn)高效調(diào)試這一主題,本書深入系統(tǒng)地介紹了以調(diào)試器為核心的各種軟件調(diào)試技術(shù)。本書共30章,分為6篇。第1篇介紹了軟件調(diào)試的概況和簡要?dú)v史。第2篇以英特爾架構(gòu)(IA)的CPU為例,介紹了計(jì)算機(jī)系統(tǒng)的硬件核心所提供的調(diào)試支持,包括異常、斷點(diǎn)指令、單步執(zhí)行標(biāo)志、分支監(jiān)視、JTAG和MCE等。第3篇以Windows操作系統(tǒng)為例,介紹了計(jì)算機(jī)系統(tǒng)的軟件核心中的調(diào)試設(shè)施,包括內(nèi)核調(diào)試引擎、用戶態(tài)調(diào)試子系統(tǒng)、異常處理、驗(yàn)證器、錯誤報(bào)告、事件追蹤、故障轉(zhuǎn)儲、硬件錯誤處理等。第4篇以Visual C/C++編譯器為例,介紹了生產(chǎn)軟件的主要工具的調(diào)試支持,重點(diǎn)討論了編譯期檢查、運(yùn)行期檢查及調(diào)試符號。第5篇討論了軟件的可調(diào)試性,探討了如何在軟件架構(gòu)設(shè)計(jì)和軟件開發(fā)過程中加入調(diào)試支持,使軟件更容易被調(diào)試。在前5篇內(nèi)容的基礎(chǔ)上,第6篇首先介紹了調(diào)試器的發(fā)展歷史、典型功能和實(shí)現(xiàn)方法,然后全面介紹了WinDBG調(diào)試器,包括它的模塊結(jié)構(gòu)、工作模型、使用方法和主要調(diào)試功能的實(shí)現(xiàn)細(xì)節(jié)。 本書是對軟件調(diào)試技術(shù)在過去50年中所取得成就的全面展示,也是對作者本人在軟件設(shè)計(jì)和系統(tǒng)開發(fā)第一線奮戰(zhàn)10多年的經(jīng)驗(yàn)總結(jié)。本書理論與實(shí)踐緊密結(jié)合,選取了大量具有代表性和普遍意義的技術(shù)細(xì)節(jié)進(jìn)行討論,是學(xué)習(xí)軟件調(diào)試技術(shù)的寶貴資料,適合每一位希望深刻理解軟件和自由駕馭軟件的人閱讀,特別是從事軟件開發(fā)、測試、支持的技術(shù)人員和有關(guān)的研究人員。
書籍目錄
第1篇 緒論 第1章 軟件調(diào)試基礎(chǔ) 1.1 簡介 1.2 基本特征 1.3 簡要?dú)v史 1.4 分類 1.5 調(diào)試技術(shù)概覽 1.6 錯誤與缺欠 1.7 與軟件工程的關(guān)系 1.8 本章總結(jié)第2篇 CPU的調(diào)試支持 第2章 CPU基礎(chǔ) 2.1 指令和指令集 2.2 IA-32處理器 2.3 CPU的操作模式 2.4 寄存器 2.5 理解保護(hù)模式 2.6 段機(jī)制 2.7 分頁機(jī)制(Paging) 2.8 系統(tǒng)概貌 2.9 本章總結(jié) 第3章 中斷和異常 3.1 概念和差異 3.2 異常的分類 3.3 異常例析 3.4 中斷/異常優(yōu)先級 3.5 中斷/異常處理 3.6 本章總結(jié) 第4章 斷點(diǎn)和單步執(zhí)行 4.1 軟件斷點(diǎn) 4.2 硬件斷點(diǎn) 4.3 陷阱標(biāo)志 4.4 實(shí)模式調(diào)試器例析 4.5 本章總結(jié) 第5章 分支記錄和性能監(jiān)視 5.1 分支監(jiān)視概覽 5.2 使用寄存器的分支記錄 5.3 使用內(nèi)存的分支記錄 5.4 DS示例:CpuWhere 5.5 性能監(jiān)視 5.6 本章總結(jié) 第6章 機(jī)器檢查架構(gòu)(MCA) 6.1 奔騰處理器的機(jī)器檢查機(jī)制 6.2 MCA 6.3 編寫MCA軟件 6.4 本章總結(jié) 第7章 JTAG調(diào)試 7.1 簡介 7.2 JTAG原理 7.3 JTAG應(yīng)用 7.4 IA-32處理器的JTAG支持 7.5 本章總結(jié)第3篇 操作系統(tǒng)的調(diào)試支持 第8章 Windows概要 8.1 簡介 8.2 進(jìn)程和進(jìn)程空間 8.3 內(nèi)核模式和用戶模式 8.4 架構(gòu)和系統(tǒng)部件 8.5 本章總結(jié) 第9章 用戶態(tài)調(diào)試模型 9.1 概覽 9.2 采集調(diào)試消息 9.3 發(fā)送調(diào)試消息 9.4 調(diào)試子系統(tǒng)服務(wù)器(XP之后) 9.5 調(diào)試子系統(tǒng)服務(wù)器(XP之前) 9.6 比較兩種模型 9.7 NTDLL中的調(diào)試支持例程 9.8 調(diào)試API 224 9.9 本章總結(jié) 第10章 用戶態(tài)調(diào)試過程 10.1 調(diào)試器進(jìn)程 10.2 被調(diào)試進(jìn)程 10.3 從調(diào)試器中啟動被調(diào)試程序 10.4 附加到已經(jīng)啟動的進(jìn)程 10.5 處理調(diào)試事件 10.6 中斷到調(diào)試器 10.7 輸出調(diào)試字符串 10.8 終止調(diào)試會話 10.9 本章總結(jié) 第11章 中斷和異常管理 11.1 中斷描述符表 11.2 異常的描述和登記 11.3 異常分發(fā)過程 11.4 結(jié)構(gòu)化異常處理(SEH) 11.5 向量化異常處理(VEH) 11.6 本章總結(jié) 第12章 未處理異常和JIT調(diào)試 12.1 簡介 12.2 默認(rèn)的異常處理器 12.3 未處理異常過濾函數(shù) 12.4 應(yīng)用程序錯誤對話框 12.5 JIT調(diào)試和Dr. Watson 12.6 頂層異常過濾函數(shù) 12.7 Dr. Watson 12.8 DRWTSN32的日志文件 12.9 用戶態(tài)轉(zhuǎn)儲文件 12.10 本章總結(jié) 第13章 硬錯誤和藍(lán)屏 13.1 硬錯誤提示 13.2 藍(lán)屏終止(BSOD) 13.3 系統(tǒng)轉(zhuǎn)儲文件 13.4 分析系統(tǒng)轉(zhuǎn)儲文件 13.5 輔助的錯誤提示方法 13.6 配置錯誤提示機(jī)制 13.7 防止濫用錯誤提示機(jī)制 13.8 本章總結(jié) 第14章 錯誤報(bào)告 14.1 WER 1.0 14.2 系統(tǒng)錯誤報(bào)告 14.3 WER服務(wù)器端 14.4 WER 2.0 14.5 CER 14.6 本章總結(jié) 第15章 日志 15.1 日志簡介 15.2 ELF的架構(gòu) 15.3 ELF的數(shù)據(jù)組織 15.4 察看和使用ELF日志 15.5 CLFS的組成和原理 15.6 CLFS的使用方法 15.7 本章總結(jié) 第16章 事件追蹤 16.1 簡介 16.2 ETW的架構(gòu) 16.3 提供ETW消息 16.4 控制ETW會話 16.5 消耗ETW消息 16.6 格式描述 16.7 NT Kernel Logger 16.8 Global Logger Session 16.9 Crimson API 16.10 本章總結(jié) 第17章 WHEA 17.1 目標(biāo)和架構(gòu) 17.2 錯誤源 17.3 錯誤處理過程 17.4 錯誤持久化 17.5 注入錯誤 17.6 本章總結(jié) 第18章 內(nèi)核調(diào)試引擎 18.1 概覽 18.2 連接 18.3 啟用 18.4 初始化 18.5 內(nèi)核調(diào)試協(xié)議 18.6 與內(nèi)核交互 18.7 建立和維持連接 18.8 本地內(nèi)核調(diào)試 18.9 本章總結(jié) 第19章 Windows的驗(yàn)證機(jī)制 19.1 簡介 19.2 驅(qū)動驗(yàn)證器的工作原理 19.3 使用驅(qū)動驗(yàn)證器 19.4 應(yīng)用程序驗(yàn)證器的工作原理 19.5 使用應(yīng)用程序驗(yàn)證器 19.6 本章總結(jié)第4篇 編譯器的調(diào)試支持 第20章 編譯和編譯期檢查 20.1 程序的構(gòu)建過程 20.2 編譯 20.3 Visual C++編譯器 20.4 編譯錯誤和警告 20.5 編譯期檢查 20.6 標(biāo)準(zhǔn)標(biāo)注語言 20.7 本章總結(jié) 第21章 運(yùn)行庫和運(yùn)行期檢查 21.1 C/C++運(yùn)行庫 21.2 鏈接運(yùn)行庫 21.3 運(yùn)行庫的初始化和清理 21.4 運(yùn)行期檢查 21.5 報(bào)告運(yùn)行期檢查錯誤 21.6 本章總結(jié) 第22章 棧和函數(shù)調(diào)用 22.1 簡介 22.2 棧的創(chuàng)建過程 22.3 CALL和RET指令 22.4 局部變量和棧幀 22.5 幀指針省略(FPO) 22.6 棧指針檢查 22.7 調(diào)用協(xié)定 22.8 ??臻g的增長和溢出 22.9 棧下溢 22.10 緩沖區(qū)溢出 22.11 變量檢查 22.12 基于Cookie的安全檢查 22.13 本章總結(jié) 第23章 堆和堆檢查 23.1 理解堆 23.2 堆的創(chuàng)建和銷毀 23.3 分配和釋放堆塊 23.4 堆的內(nèi)部結(jié)構(gòu) 23.5 低碎片堆(LFH) 23.6 堆的調(diào)試支持 23.7 ?;厮輸?shù)據(jù)庫 23.8 堆溢出和檢測 23.9 頁堆 23.10 準(zhǔn)頁堆 23.11 CRT堆 23.12 CRT堆的調(diào)試堆塊 23.13 CRT堆的調(diào)試功能 23.14 堆塊轉(zhuǎn)儲 23.15 泄漏轉(zhuǎn)儲 23.16 本章總結(jié) 第24章 異常處理代碼的編譯 24.1 概覽 24.2 FS:[0]鏈條 24.3 遍歷FS:[0]鏈條 24.4 執(zhí)行異常處理函數(shù) 24.5 __try{}__except()結(jié)構(gòu) 24.6 安全問題 24.7 本章總結(jié) 第25章 調(diào)試符號 25.1 名稱修飾 25.2 調(diào)試信息的存儲格式 25.3 目標(biāo)文件中的調(diào)試信息 25.4 PE文件中的調(diào)試信息 25.5 DBG文件 25.6 PDB文件 25.7 有關(guān)的編譯和鏈接選項(xiàng) 25.8 PDB文件中的數(shù)據(jù)表 25.9 本章總結(jié)第5篇 可調(diào)試性 第26章 可調(diào)試性概覽 26.1 簡介 26.2 Showstopper和未雨綢繆 26.3 基本原則 26.4 不可調(diào)試代碼 26.5 可調(diào)試性例析 26.6 與安全、性能和商業(yè)秘密的關(guān)系 26.7 本章總結(jié) 第27章 可調(diào)試性的實(shí)現(xiàn) 27.1 角色和職責(zé) 27.2 可調(diào)試架構(gòu) 27.3 通過?;厮輰?shí)現(xiàn)可追溯性 27.4 數(shù)據(jù)的可追溯性 27.5 可觀察性的實(shí)現(xiàn) 27.6 自檢和自動報(bào)告 27.7 本章總結(jié)第6篇 調(diào)試器 第28章 調(diào)試器概覽 28.1 TX-0計(jì)算機(jī)和FLIT調(diào)試器 28.2 小型機(jī)和DDT調(diào)試器 28.3 個人計(jì)算機(jī)和它的調(diào)試器 28.4 調(diào)試器的功能 28.5 分類標(biāo)準(zhǔn) 28.6 實(shí)現(xiàn)模型 28.7 經(jīng)典架構(gòu) 28.8 HPD標(biāo)準(zhǔn) 28.9 本章總結(jié) 第29章 WinDBG及其實(shí)現(xiàn) 29.1 WinDBG溯源 29.2 C階段的架構(gòu) 29.3 重構(gòu) 29.4 調(diào)試器引擎的架構(gòu) 29.5 調(diào)試目標(biāo) 29.6 調(diào)試會話 29.7 接收和處理命令 29.8 本章總結(jié) 第30章 WinDBG用法詳解 30.1 工作空間 30.2 命令概覽 30.3 用戶界面 30.4 輸入和執(zhí)行命令 30.5 建立調(diào)試會話 30.6 終止調(diào)試會話 30.7 理解上下文 30.8 調(diào)試符號 30.9 事件處理 30.10 控制調(diào)試目標(biāo) 30.11 單步執(zhí)行 30.12 使用斷點(diǎn) 30.13 控制進(jìn)程和線程 30.14 觀察?! ?0.15 分析內(nèi)存 30.16 遍歷鏈表 30.17 調(diào)用目標(biāo)程序的函數(shù) 30.18 命令程序 30.19 本章總結(jié)附錄A 示例程序列表附錄B WinDBG標(biāo)準(zhǔn)命令列表索引
章節(jié)摘錄
第1篇 緒論 第1章 軟件調(diào)試基礎(chǔ) 1955年,一個名叫Computer Usage Corporation(CUC)的公司誕生了,它是世界上第一個專門從事軟件開發(fā)和服務(wù)的公司。CUC公司的創(chuàng)始人是Elmer Kubie和John w Sheldon,他們都在IBM工作過。從當(dāng)時計(jì)算機(jī)硬件的迅速發(fā)展中,他們看到了軟件方面所潛在的機(jī)遇。CUC的誕生標(biāo)志著一個新興的產(chǎn)業(yè)正式起步了?! ∨c其他產(chǎn)業(yè)相比,軟件產(chǎn)業(yè)的發(fā)展速度是驚人的。短短50幾年后,我們已經(jīng)難以統(tǒng)計(jì)世界上共有多少個軟件公司,只知道一定是一個很龐大的數(shù)字,而且這個數(shù)量還在不斷增大。同時,軟件產(chǎn)品的數(shù)量也達(dá)到了難以統(tǒng)計(jì)的程度,各種各樣的軟件已經(jīng)滲透到人類生產(chǎn)和生活的各個領(lǐng)域,越來越多的人開始依賴軟件工作和生活?! ∨c傳統(tǒng)的產(chǎn)品相比,軟件產(chǎn)品具有根本的不同,其生產(chǎn)過程也有著根本的差異。在開發(fā)軟件的整個過程中,存在非常多的不確定性因素。在一個軟件真正完成之前,很難預(yù)計(jì)它的完成日期。很多軟件項(xiàng)目都經(jīng)歷了多次的延期,還有很多中途夭折。直到今天,人們還沒有找到一種有效的方法來控制軟件的生產(chǎn)過程。導(dǎo)致軟件生產(chǎn)難以控制的根本原因是來源于軟件本身的復(fù)雜性。一個軟件的規(guī)模越大,它的復(fù)雜度也越高?! 『唵蝸碚f,軟件是程序(program)和文檔(document)的集合,程序的核心內(nèi)容便是按一定順序排列的一系列指令(instruction)。如果把每個指令看作一塊積木,那么軟件開發(fā)就是使用這些積木修建一個讓CPU(中央處理器)在其中運(yùn)行的交通系統(tǒng)。這個系統(tǒng)中有很多條不同特征的道路(函數(shù))。有些道路只允許一輛車在上面行駛,一輛車駛出后另一輛才能進(jìn)入,有些道路可以讓無數(shù)輛車同時在上面飛奔。這些道路都是單行道,只可以沿一個方向行駛。在這些道路之間,除了明確的入口(entry)和出口(exit)之外,還可以通過中斷和異常等機(jī)制從一條路飛越到另一條,另一條又可以飛轉(zhuǎn)到第三條或直接飛回到第一條。在這個系統(tǒng)中行駛的車輛也很特殊,它們速度很快,而且“無人駕駛”,完全不知道會跑到哪里,唯一的原則就是上了一條路便沿著它向前跑…… 如果說軟件的執(zhí)行過程就好像是CPU在無數(shù)條道路(指令流)間飛奔,那么開發(fā)軟件的過程就是設(shè)計(jì)和構(gòu)建這個交通網(wǎng)絡(luò)的過程。其基本目標(biāo)是要讓CPU在這個網(wǎng)絡(luò)中奔跑時可以完成需求(requirement)中所定義的功能。對這個網(wǎng)絡(luò)的其他要求通常還有可靠(reliable)、靈活(flexible)、健壯(robust)、易于維護(hù)(maintainable),可以簡單地改造就能讓其他類型的車輛(CPU)在上面行駛(portable)…… 開發(fā)一個滿足以上要求的軟件系統(tǒng)不是一件簡單的事,通常需要經(jīng)歷分析(analysis)、設(shè)計(jì)(design)、編碼(code)和測試(test)等多個環(huán)節(jié)。通過測試并發(fā)布(release)后,還需要維護(hù)(maintain)和支持(support)工作。在以上環(huán)節(jié)中,每一步都可能遇到這樣那樣的技術(shù)難題?! ≡谲浖澜缰?,螺絲刀、萬用表等傳統(tǒng)的探測和修理工具都不再適用了,取而代之的是以調(diào)試器為核心的各種軟件調(diào)試(Software Debugging)工具?! ≤浖{(diào)試的基本手段有斷點(diǎn)、單步執(zhí)行、?;厮莸龋涑踔跃褪歉櫤陀涗汣PU執(zhí)行軟件的過程,把動態(tài)的瞬間凝固下來供檢查和分析?! ≤浖{(diào)試的基本目標(biāo)是定位軟件中存在的設(shè)計(jì)錯誤(bug)。但除此之外,軟件調(diào)試技術(shù)和工具還有很多其他用途。比如,分析軟件的工作原理,分析系統(tǒng)崩潰,輔助解決系統(tǒng)和硬件問題等?! 「哦灾?,軟件是通過指令的組合來指揮硬件,既簡單,又復(fù)雜,充滿神秘與挑戰(zhàn)。而軟件調(diào)試是幫助人們探索和征服這個神秘世界的有力工具?! 〉?章 軟件調(diào)試基礎(chǔ) 著名的計(jì)算機(jī)科學(xué)家Brian Kernighan曾經(jīng)說過,軟件調(diào)試要比編寫代碼困難一倍,如果你發(fā)揮出了最佳才智編寫代碼,那么你的智商便不足以調(diào)試這個代碼?! ×硪环矫妫浖{(diào)試是軟件開發(fā)和維護(hù)中非常頻繁的一項(xiàng)任務(wù),幾乎在軟件生命周期的每個階段,都有很多這樣那樣的問題需要進(jìn)行調(diào)試?! ∫环矫媸请y度很高,另一方面是任務(wù)很多。因此,在一個典型的軟件團(tuán)隊(duì)中,花費(fèi)在軟件調(diào)試上的人力和時間通常是很可觀的。據(jù)不完全統(tǒng)計(jì),一半以上的軟件工程師把一半以上的時間用在軟件調(diào)試上。很多時候,調(diào)試一個軟件問題可能就需要幾天乃至幾周的時間。從這個角度來看,提高軟件工程師的調(diào)試效率對于提高軟件團(tuán)隊(duì)的工作效率有著重要意義。 本書旨在從多個角度和多個層次解析軟件調(diào)試的原理、方法和技巧。在分別深入介紹這些內(nèi)容之前,本章將做一個概括性的介紹,使讀者了解一個簡單的全貌,為閱讀后面的章節(jié)做準(zhǔn)備?! ?.1 簡介 這一節(jié)我們首先給出軟件調(diào)試的解釋性定義,而后介紹軟件調(diào)試的基本過程?! ?.1.1 定義 首先,什么是軟件調(diào)試?我們不妨從英文的原詞software debug說起,debug是在bug一詞前面加上詞頭de,意思是分離和去除bug?! ug的本意就是昆蟲,但至少早在19世紀(jì)時,人們就開始使用這個詞來描述電子設(shè)備中的設(shè)計(jì)缺欠,著名發(fā)明家托馬斯?阿爾瓦?愛迪生(1847—2—11—1931—10-18)就使用這個詞來描述電路方面的設(shè)計(jì)錯誤?! £P(guān)于Bug一詞在計(jì)算機(jī)方面的應(yīng)用流傳著一個有趣的故事。時間是在20世紀(jì)40年代,當(dāng)時的電子計(jì)算機(jī)都還非常龐大,數(shù)量也非常少,主要用在軍事方面。1944年制造完成的Mark 1,1946年2月開始運(yùn)行的ENIAC(Electronic Numerical Integrator AndComputer)和1947年完成的Mark Ⅱ是其中赫赫有名的幾臺。Mark 1是由哈佛大學(xué)的HowardAiken教授設(shè)計(jì),IBM公司制造的,Mark Ⅱ是由美國海軍出資制造的。與使用電子管制造的ENIAC不同,Markl和MarkⅡ主要是使用開關(guān)和繼電器制造的。另外,Mark l和Mark Ⅱ都是從紙帶或磁帶上讀取指令并執(zhí)行的,因此,它們不屬于從內(nèi)存讀取和執(zhí)行指令的存儲程序計(jì)算機(jī)(stored—program computer)。 1947年9月9日,當(dāng)人們測試Mark Ⅱ計(jì)算機(jī)時,它突然發(fā)生了故障。經(jīng)過幾個小時的檢查后,工作人員發(fā)現(xiàn)一只飛蛾被打死在面板F的第70號繼電器中。當(dāng)把這個飛蛾取出后,機(jī)器便恢復(fù)了正常。當(dāng)時為Mark Ⅱ計(jì)算機(jī)工作的著名女科學(xué)家GraceHopper將這只飛蛾粘貼到當(dāng)天的工作手冊中(見圖1.1),并在上面加了一行注釋,“Firstactual case ofbug being found”,當(dāng)時的時間是15:45。隨著這個故事的廣為流傳,越來越多的人開始使用Bug一詞來指代計(jì)算機(jī)中的設(shè)計(jì)錯誤,并把Grace Hopper上登記的那只飛蛾看作是計(jì)算機(jī)歷史上第一個被記錄在文檔(documented)中的Bug。圖1—1 計(jì)算機(jī)歷史上第一個被記錄在文檔中的Bug在Bug一詞廣泛使用后,人們自然地開始使用debug這個詞來泛指排除錯誤的過程。關(guān)于誰最先創(chuàng)造和使用了這個詞,目前還沒有公認(rèn)的說法,但是可以肯定的是,Grace Hopper在20世紀(jì)50年代發(fā)表的很多論文中就已頻繁使用這個詞了。因此可以肯定地說,在20世紀(jì)50年代人們已經(jīng)開始使用這個詞來表達(dá)軟件調(diào)試這一含義,而且一直延續(xù)到今天?! ”M管從字面上看,debug的直接意思就是去除Bug,但它實(shí)際上包含了尋找和定位Bug。因?yàn)槿コ鼴ug的前提是要找到Bug,如何找到Bug大都比發(fā)現(xiàn)后去除它要難得多。而且,隨著計(jì)算機(jī)系統(tǒng)的發(fā)展,軟件調(diào)試已經(jīng)變得越來越不像在繼電器間“捉蟲”那樣輕而易舉了。因此,在臺灣,人們把software debug翻譯為軟件偵錯。這個翻譯沒有按照英文原詞的字面含義直譯,超越了原本的單指“去除”的境界,融入了偵查的含義,是個很不錯的意譯。 在大陸,通常將software debug翻譯為軟件調(diào)試,泛指重現(xiàn)軟件故障(failure)、定位故障根源,并最終解決軟件問題的過程。這種理解與英語文獻(xiàn)中對software debug的深層解釋也是一致的。如微軟的計(jì)算機(jī)詞典(Microsoft Computer Dictionary,FifthEdition)對debug一詞的解釋是: debug vb.To detect,locate,and correct logical or syntactical errors in a program ormalfunctions in hardware. 對軟件調(diào)試的另一種更通俗的解釋是指使用調(diào)試工具求解各種軟件問題的過程,例如跟蹤軟件的執(zhí)行過程,探索軟件本身或與其配套的其他軟件,或者硬件系統(tǒng)的工作原理等,這些過程有可能是為了去除軟件缺欠,也可能不是。 1.1.2 基本過程 盡管取出那只飛蟲非常輕松,但是找到它還是耗費(fèi)了幾個小時的時間。因此,軟件調(diào)試從一開始實(shí)際上就包含了定位錯誤和去除錯誤這兩個基本步驟。進(jìn)一步講,一個完整的軟件調(diào)試過程是圖1—2所示的循環(huán)過程,它由以下幾個步驟組成?! 〉谝唬噩F(xiàn)故障,通常是在用于調(diào)試的系統(tǒng)上重復(fù)導(dǎo)致故障的步驟,使要解決的問題出現(xiàn)在被調(diào)試的系統(tǒng)中。 第二,定位根源,即綜合利用各種調(diào)試工具,使用各種調(diào)試手段尋找導(dǎo)致軟件故障的根源(root cause)。通常測試人員報(bào)告和描述的是軟件故障所表現(xiàn)出的外在癥狀,比如界面或執(zhí)行結(jié)果中所表現(xiàn)出的異常;或者是與軟件需求(requirement)和功能規(guī)約(function specification)不符的地方,即所謂的軟件缺欠(defect)。而這些表面的缺欠總是由于一個或多個內(nèi)在因素所導(dǎo)致的,這些內(nèi)因要么是代碼的行為錯誤,要么是不行為錯誤(該做而未做)。定位根源就是要找到導(dǎo)致外在缺欠的內(nèi)因?! 〉谌剿骱蛯?shí)現(xiàn)解決方案,即根據(jù)尋找到的故障根源、資源情況、緊迫程度等設(shè)計(jì)和實(shí)現(xiàn)解決方案?! 〉谒?,驗(yàn)證方案,在目標(biāo)環(huán)境中測試方案的有效性,又稱為回歸(regress)測試。如果問題已經(jīng)解決,那么就可以關(guān)閉問題。如果沒有解決,則回到第3步調(diào)整和修改解決方案?! D1—2軟件調(diào)試過程 在以上各步驟中,定位根源常常是最困難也是最關(guān)鍵的步驟,它是軟件調(diào)試過程的核心和靈魂。如果沒有找到故障根源,那么解決方案便很可能是隔靴搔癢,或者頭痛醫(yī)腳,有時似乎緩解了問題,但事實(shí)上沒有徹底解決問題,甚至是白白浪費(fèi)時間。 1.2 基本特征 上一節(jié)介紹了軟件調(diào)試的定義和基本過程。本節(jié)將進(jìn)一步介紹它的基本特征,我們將分3個方面來討論。 1.2.1 難度大 誠如Brian Kernighan先生所說的,軟件調(diào)試是一項(xiàng)復(fù)雜度高、難度大的任務(wù)。以下是導(dǎo)致這種復(fù)雜性的幾個主要因素?! 〉谝?,如果把定位軟件錯誤看作是一種特別的搜索問題,那么它通常是個很復(fù)雜的搜索問題。首先,被搜索的目標(biāo)空間是軟件問題所發(fā)生的系統(tǒng),從所包含的信息量來看,這個空間通常是很龐大的,因?yàn)橐粋€典型的計(jì)算機(jī)系統(tǒng)中包含著幾十個硬件部件、數(shù)千個軟件模塊,每個模塊又包含著以KB或MB為單位的大量指令(代碼)。另一方面,這個搜索問題并沒有明確的目標(biāo)和關(guān)鍵字,通常只知道不是非常明確的外在癥狀,必須通過大量的分析,才能逐步接近真正的內(nèi)在原因?! 〉诙瑸榱颂綄栴}的根源,很多時候必須深入到被調(diào)試模塊或系統(tǒng)的底層,研究內(nèi)部的數(shù)據(jù)和代碼。與頂層不同,底層的數(shù)據(jù)大多是以原始形態(tài)存在的,理解和分析的難度比頂層要大。舉例來說,對于頂層看到的文字信息,在底層看到的可能只是這些文字的某種編碼(ANSl或UNICODE等)。對于代碼而言,底層意味著低級語言或匯編語言,甚至機(jī)器碼,因?yàn)楫?dāng)無法進(jìn)行源代碼級的調(diào)試時,我們不得不進(jìn)行匯編一級的跟蹤和分析。對于通信有關(guān)的問題,底層意味著需要觀察原始的通信數(shù)據(jù)包和檢查包的各個部分。另外,很多底層的數(shù)據(jù)和行為是沒有文檔的,不得不做大量的跟蹤和分析才能摸索出一些線索和規(guī)律。從APl的角度來看,底層意味著不僅要理解API的原型和使用方法,有時還必須知道它內(nèi)部是如何實(shí)現(xiàn)的,執(zhí)行了哪些操作,這一點(diǎn)也論證了Brian Kernighan所說的調(diào)試要比編寫代碼困難。
編輯推薦
ACM院士和調(diào)試技術(shù)先驅(qū)Jack B.Dennis教授做歷史回顧計(jì)算機(jī)和操作系統(tǒng)領(lǐng)域資深專家David A.Solomon撰寫序言。調(diào)試高手筆耕三載集十余年經(jīng)驗(yàn)成百萬言篇,業(yè)內(nèi)專家鼎力相助,匯五十年精華補(bǔ)軟件界空白?! ∧鷮W(xué)習(xí)到: CPU的調(diào)試支持,包括異常、斷點(diǎn)、單步執(zhí)行、分支監(jiān)視、JTAG、MCE等?! indows操作系統(tǒng)中的調(diào)試設(shè)施,包括內(nèi)核調(diào)試引擎、用戶態(tài)調(diào)試予系統(tǒng)、驗(yàn)證器、Dr.Watson、WER、ETW、故障轉(zhuǎn)儲、WHEA等?! isual C/C++編譯器的調(diào)試支持,包括編譯期檢查、運(yùn)行期檢查,以及調(diào)試符號?! inDBG調(diào)試器的發(fā)展歷史、模塊結(jié)構(gòu)、工作模型、使用方法、主要調(diào)試功能的實(shí)現(xiàn)細(xì)節(jié),以及遍布全書的應(yīng)用實(shí)例?! ?nèi)核調(diào)試、用戶態(tài)調(diào)試、JIT調(diào)試、遠(yuǎn)程調(diào)試的原理、實(shí)現(xiàn)和用法。異常的概念、分發(fā)方法、處理方法(SEH、VEH、CppEH),未處理異常,以及編譯器編譯異常處理代碼的方法。 調(diào)試符號的作用、產(chǎn)生過程、存儲格式和使用方法。棧和堆的結(jié)構(gòu)布局、工作原理和有關(guān)的軟件問題,包括棧的自動增長和溢出,緩;中區(qū)溢出,溢出攻擊,內(nèi)存泄漏,堆崩潰等。 軟件的可調(diào)試性和提高可調(diào)試性的方法?! 〈送?,書中還詮釋了很多較難理解的概念,思考了一系列耐人深思和具有普遍意義的問題。本書是對軟件調(diào)試技術(shù)在過去50年中所取得成就的全面展示,也是筆者本人在軟件設(shè)計(jì)和系統(tǒng)開發(fā)第一線奮戰(zhàn)10多年的經(jīng)驗(yàn)總結(jié)。本書適合每一位希望深刻理解軟件和自由駕馭軟件的人閱讀,不論您是否直接參與軟件開發(fā)和測試;不論您是熱愛軟件,還是憎恨軟件;不論您是想發(fā)現(xiàn)軟件中的瑕疵,還是想領(lǐng)略其中蘊(yùn)含的智慧! 本書直面軟件工程中的最困難任務(wù)——偵錯 圍繞軟件世界中的最強(qiáng)大工具——調(diào)試器 全方位展示了軟件調(diào)試技術(shù)的無比威力和無窮魅力 80個示例程序的源程序文件和項(xiàng)目文件 瀏覽符號文件的SymView工具 與內(nèi)核調(diào)試引擎對話的KdTalker工具 直接瀏覽用戶態(tài)轉(zhuǎn)儲文件的UdmpView工具 顯示CPU執(zhí)行軌跡(分支)的Cpuwhere工具 觀察IDT、GDT和系統(tǒng)對象的SOZOOmer工具 本書是對軟件調(diào)試技術(shù)在過去50年中所取得成就的全面展示,也是對作者本人在軟件設(shè)計(jì)和系統(tǒng)開發(fā)第一線奮戰(zhàn)10多年的經(jīng)驗(yàn)總結(jié)。全書共分6篇30章,選取了大量具有代表性和普遍意義的技術(shù)細(xì)節(jié)進(jìn)行討論,包括CPU的調(diào)試支持、操作系統(tǒng)的調(diào)試支持、編譯器的調(diào)試支持、WinDBG及其實(shí)現(xiàn)等,是學(xué)習(xí)軟件調(diào)試技術(shù)的寶貴資料。該書可供各大專院校作為教材使用,也可供從事相關(guān)工作的人員作為參考用書使用。
圖書封面
圖書標(biāo)簽Tags
無
評論、評分、閱讀與下載