第Ⅰ部分 調試概述
第1章 錯誤來源和除錯方法
1.1 錯誤及其調試
1.1.1 什么是錯誤
1.1.2 錯誤產生的原因和解決辦法
1.1.3 規(guī)劃調試
1.2 優(yōu)秀調試人員的必備技能
1.2.1 所需技能
1.2.2 學習各種技能
1.3 調試過程
1.3.1 步驟1:重現錯誤
1.3.2 步驟2:描述錯誤
1.3.3 步驟3:總是假設是您自己造成的錯誤
1.3.4 步驟4:分而治之
1.3.5 步驟5:創(chuàng)造性地思考
1.3.6 步驟6:借助于工具
1.3.7 步驟7:開始大規(guī)模調試
1.3.8 步驟8:驗證錯誤已經被更正
1.3.9 步驟9:學習和與人分享
1.3.10 調試過程的最終秘密
1.3.11 本章小結
第2章 開始調試
2.1 跟蹤所有更改直至項目完成
2.1.1 版本控制系統(tǒng)
2.1.2 錯誤跟蹤系統(tǒng)
2.1.3 選擇適當的系統(tǒng)
2.2 在進度表中安排時間建立調試系統(tǒng)
2.2.1 保證所有版本中都帶調試符號
2.2.2 把托管代碼中的編譯警告視為編譯錯誤
2.2.3 對于本機代碼將大多數編譯警告視為編譯錯誤
2.2.4 了解本機代碼中DLL的加載位置
2.2.5 如何處理托管模塊及其基址
2.2.6 為發(fā)布版本設計輕量級的診斷系統(tǒng)
2.3 必須進行頻繁生成和冒煙測試
2.3.1 頻繁生成
2.3.2 冒煙測試
2.4 盡早創(chuàng)建安裝程序
2.5 QA必須測試調試版本
2.6 安裝操作系統(tǒng)調試符號并建立符號庫
2.7 本章小結
第3章 邊編碼邊調試
3.1 斷言
3.1.1 如何斷言以及斷言什么
3.1.2 在.NET Windows窗體或控制臺應用程序中設置斷言
3.1.3 在ASP.NET程序和XML Web服務中設置斷言
3.1.4 在本機C++程序中設置斷言
3.1.5 Visual C++中不同類型的斷言
3.1.6 SUPERASSERT
3.2 跟蹤、跟蹤、再跟蹤
3.2.1 在Windows窗體應用和控制臺.NET應用程序中跟蹤
3.2.2 在ASP.NET應用程序和XML WEB Services中跟蹤
3.2.3 在本機C++應用程序中跟蹤
3.3 注釋、注釋、再注釋
3.4 信任自己,但要進行驗證(單元測試)
3.5 本章小結
第Ⅱ部分 強大的調試技術
第4章 操作系統(tǒng)對調試的支持以及Win32調試器工作原理
4.1 Windows調試器的類型
4.1.1 用戶模式調試器
4.1.2 內核模式調試器
4.2 Windows操作系統(tǒng)對調試對象的支持
4.2.1 實時(JIT)調試
4.2.2 在調試器中自動啟動(映像文件執(zhí)行選項)
4.3 MinDBG:一個簡單的Win32調試器
4.4 WDBG:真正的調試器
4.4.1 讀/寫內存
4.4.2 斷點和單步執(zhí)行
4.4.3 符號表、符號引擎和堆棧遍歷
4.4.4 Step Into、Step Over和Step Out
4.5 編寫您自己的調試器
4.6 對WDBG的改進建議
4.7 本章小結
第5章 Visual Studio.NET調試器高級用法
5.1 高級斷點及其用法
5.1.1 斷點設置技巧
5.1.2 在任何函數位置快速中斷
5.1.3 位置斷點智能特性
5.2 Watch窗口
5.2.1 在Watch窗口中調用方法
5.2.2 Set Next Statement命令
5.3 本章小結
第6章 Visual Studio.NET高級.NET調試
6.1 .NET程序中的高級斷點
6.1.1 條件表達式
6.2 Watch窗口
6.2.1 自動展開自定義類型
6.3 提示與技巧
6.3.1 DebuggerStepThroughAttribute和DebuggerHiddenAttribute
6.3.2 混合模式調試
6.3.3 遠程調試
6.4 ILDASM和Microsoft中間語言
6.4.1 開始學習ILDASM
6.4.2 公共語言運行庫(CLR)
6.4.3 MSIL、局部變量和參數
6.4.4 重要指令
6.5 其他逆向工程工具
6.6 本章小結
第7章 Visual Studio.NET本機代碼高級調試技術
7.1 本機應用程序的高級斷點
7.1.1 高級斷點語法
7.1.2 系統(tǒng)或導出函數的斷點
7.1.3 條件表達式
7.1.4 數據斷點
7.1.5 更好的數據斷點
7.2 Watch窗口
7.2.1 數據的格式化和表達式的計算
7.2.2 在Watch窗口中記錄代碼執(zhí)行時間
7.2.3 未歸檔的偽寄存器
7.2.4 自動展開自己的類型
7.3 遠程調試
7.4 提示與技巧
7.4.1 調試插入的代碼
7.4.2 Memory窗口和自動內存計算
7.4.3 監(jiān)視異常
7.4.4 處理符號的更多技巧
7.4.5 與Windows 2000進程分離
7.4.6 處理轉儲文件
7.5 x86匯編語言
7.5.1 CPU基礎
7.5.2 淺談Visual C++.NET內聯(lián)匯編器
7.5.3 您需要了解的指令
7.5.4 通用序列:函數的入口和出口
7.5.5 調用過程和返回
7.5.6 調用約定
7.5.7 變量訪問;全局變量、參數和局部變量
7.5.8 更多需要了解的指令
7.5.9 字符串操作
7.5.10 常見的匯編語言結構
7.5.11 結構引用和類引用
7.5.12 完整的示例
7.5.13 Disassembly窗口
7.5.14 手動查看堆棧
7.5.15 提示與技巧
7.6 本章小結
第8章 WinDBG的高級本機代碼調試技術
8.1 要點回顧
8.2 基礎知識
8.3 調試環(huán)境
8.3.1 獲得幫助信息
8.3.2 確保加載了正確的符號
8.3.3 進程和線程
8.4 使用Command窗口進行普通調試
8.4.1 查看和計算變量
8.4.2 執(zhí)行、步進和跟蹤
8.4.3 斷點
8.4.4 異常和事件
8.4.5 控制WinDBG
8.5 神奇的擴展命令
8.5.1 加載和控制擴展
8.5.2 重要的擴展命令
8.6 處理轉儲文件
8.6.1 創(chuàng)建轉儲文件
8.6.2 打開轉儲文件
8.6.3 調試轉儲文件
8.7 Son of Strike(SOS)擴展
8.7.1 使用SOS
8.8 本章小結
第Ⅲ部分 .NET的強大調試工具和技術
第9章 擴展Visual Studio .NET IDE
9.1 使用宏進行擴展
9.1.1 宏的參數
9.1.2 與項目有關的問題
9.1.3 代碼元素
9.2 CommenTater:能解決共同面臨的棘手問題嗎?
9.3 外接程序簡介
9.3.1 修改外接程序向導生成的代碼
9.3.2 處理工具欄按鈕問題
9.3.3 創(chuàng)建工具窗口
9.3.4 使用托管代碼創(chuàng)建選項屬性頁
9.4 SuperSaver外接程序
9.5 SettingsMaster外接程序
9.5.1 SettingsMaster的實現要點
9.5.2 對SettingsMaster的改進建議
9.6 本章小結
第10章 托管異常的監(jiān)視
10.1 Profiling API簡介
10.1.1 啟動您的分析器
10.2 ProfilerLib
10.3 ExceptionMon
10.3.1 進程內調試與ExceptionMon
10.4 .NET中異常的使用
10.5 本章小結
第11章 流程跟蹤
11.1 在Profiling API中鉤掛函數
11.1.1 請求Enter和Leave通知
11.1.2 實現鉤子函數
11.1.3 內聯(lián)
11.1.4 FunctionIDMapper函數
11.2 使用FlowTrace
11.3 FlowTrace實現中的主要問題
11.4 對FlowTrace的改進建議
11.5 本章小結
第Ⅳ部分 本機代碼的強大調試工具和技術
第12章 通過崩潰時返回的地址找到源文件和行信息
12.1 創(chuàng)建和讀取MAP文件
12.1.1 MAP文件內容
12.1.2 尋找源文件、函數名和行號
12.1.3 PDB2MAP——崩潰發(fā)生后的Map文件
12.2 使用CrashFinder
12.2.1 實現要點
12.3 對CrashFinder的改進建議
12.4 本章小結
第13章 崩潰處理機制
13.1 結構化異常處理機制和C++異常處理機制
13.1.1 結構化異常處理機制
13.1.2 C++異常處理機制
13.1.3 避免使用C++異常處理
13.1.4 不要使用_set_se_translator
13.2 SetUnhandledExceptionFilter API函數
13.3 使用CrashHandler API函數
13.4 轉換EXCEPTION_POINTERS結構
13.5 小型轉儲(Minidump)
13.5.1 MiniDumpWrite Dump API
13.5.2 關于MiniDumpWrite Dump
13.6 本章小結
第14章 調試Windows服務和加載到服務中的DLL
14.1 服務的基礎知識
14.1.1 API要點
14.1.2 安全問題
14.2 調試服務
14.2.1 調試核心代碼
14.2.2 調試基本服務
14.3 本章小結
第15章 多線程死鎖
15.1 多線程編程提示和技巧
15.1.1 不要使用多線程
15.1.2 不要過多使用多線程
15.1.3 只在很小的離散程序段中使用多線程
15.1.4 在最低級別同步
15.1.5 旋轉臨界區(qū)
15.1.6 不要使用CreateThread/ExitThread
15.1.7 默認的內存管理器可能令程序失敗
15.1.8 當場進行轉儲
15.1.9 檢查代碼——并再次檢查代碼
15.1.10 在多處理器機器上進行測試
15.2 DeadlockDetection的要求
15.3 關于DeadlockDetection的高級設計問題
15.4 使用DeadlockDetection
15.5 實現DeadlockDetection
15.5.1 鉤掛導入函數
15.5.2 實現要點
15.6 對DeadlockDetection的改進建議
15.7 本章小結
第16章 自動化測試
16.1 單元測試的難點:用戶界面
16.2 對Tester的要求
16.3 使用Tester
16.3.1 Tester腳本
16.3.2 記錄腳本
16.4 實現Tester
16.4.1 TESTER.DLL通知和回放的實現
16.4.2 實現TESTREC.EXE
16.5 對Tester的改進建議
16.6 本章小結
第17章 調試C運行時庫和內存管理
17.1 調試C運行時庫的特性
17.2 使用調試C運行時庫
17.2.1 DCRT中的缺陷
17.2.2 DCRT函數
17.3 為應用程序選擇合適的C運行時庫
17.4 使用MemDumperValidator
17.4.1 在C++中使用MemDumperValidator
17.4.2 在C語言中使用MemDumperValidator
17.4.3 深層驗證
17.5 實現MemDumperValidator
17.5.1 在C++中初始化和終止
17.5.2 泄漏報告都到哪兒去了?
17.6 使用MemStress
17.6.1 有趣的壓力測試問題
17.7 操作系統(tǒng)堆
17.8 發(fā)現內存問題的技巧
17.8.1 發(fā)現未初始化的內存寫入問題
17.8.2 發(fā)現內存溢出
17.9 重要開關
17.9.1 運行時檢查開關
17.9.2 緩沖區(qū)安全檢查開關
17.10 本章小結
第18章 FastTrace:用于服務器應用程序的高性能跟蹤工具
18.1 基本問題和解決方案
18.2 使用FastTrace
18.2.1 合并跟蹤日志文件
18.3 FastTrace的實現
18.4 本章小結
第19章 優(yōu)化工作集
19.1 工作集調整
19.2 使用SWS
19.2.1 設置SWS編譯
19.2.2 使用SWS運行應用程序
19.2.3 生成和使用排序文件
19.3 實現SWS
19.3.1 _penter函數
19.3.2 .SWS文件格式和符號枚舉
19.3.3 運行時符號問題和模塊調整
19.4 對SWS的改進建議
19.5 本章小結
附錄A:閱讀Dr.Watson日志