基本介紹
內容簡介,作者簡介,目錄,
內容簡介
本書是一本介紹Windows系統上的用戶態程式排錯方法和技巧的書。本書分為4個章節,先介紹最重要的、通用的思考方法,以便制定排錯步驟;再介紹對排錯有幫助的知識點和工具;並介紹了。NETFramework(CLR)的相關知識和調試技巧;最後一章針對常見的幾大類問題進行了總結。本書案例豐富,對現實中的實際問題進行了研究,並和讀者一起分析解決辦法;本書的寫作思路為先給出問題描述,然後提供線索,再進行分析,讓讀者在閱讀中也進行思考,以提高實際解決問題的能力。本書適合希望學習排錯、調試知識的軟體開發、測試人員,希望深入學習Windows系統上用戶態程式的排錯知識的軟體開發、測試人員。
作者簡介
熊力,2004年開始在上海微軟技術支持中心擔任技術支持工程師。他所在的小組負責幫助企業客戶解決開發領域的技術難題。作者專注於.NETFramework、C/C++、COM和Web開發,現任微軟中國研發集團伺服器與開發工具事業部測試工程師。
目錄
第1章比工具、技巧和經驗都重要的是你的思考——從四個風格迥異的案例說起
1.1絕望的性能問題:ADO NET2.0竟然比1.0要慢
1.1.1問題描述
1.1.2悲觀和絕望
1.1.3換位思考
1.1.4排錯
1.1.5結論和收穫
1.1.6題外話和相關討論
Safehandle的更多討論
平衡、取捨、雙贏和RFC1925
Profiler的下載地址和相關資源
1.2不可思議:一個API同時打開了兩個檔案
1.2.1問題描述
1.2.2第一印象
1.2.3深入分析
1.2.4革命尚未成功
1.2.5結論
1.2.6題外話和相關討論
MSDN是最值得信賴的嗎
你敢說CPU壞了
DWORD和檔案長度
程式輸出0xcdcdcdcd,想到了什麼
1.3簡單的問題最棘手:稀疏平常的ASP NETSessionLost問題
1.3.1問題描述
1.3.2制定策略
1.3.3具體操作和結論
1.3.4題外話和相關討論
排查sessionlost的經驗
1.4本可以做得更好:SharePoint中文界面變英文
1.4.1問題描述
1.4.2排錯步驟
1.4.3錯過的線索
第2章彙編、異常、記憶體、同步和調試器——重要的知識點和神兵利器
2.1排錯的工具:調試器Windbg
2.1.1調試器的功能:檢查代碼和資料,保存dump檔案,斷點控制程式的執行
2.1.2符號檔案(Symbolfile),把二進制和原始碼對應起來
2.1.3一個簡單的上手程式
2.1.4用InternetExplorer來操練調試器的基本命令
vertarget檢查進程概況
!peb顯示ProcessEnvironmentBlock
lmvm檢查模組的載入信息
.reload/!sym載入符號檔案
lmf列出當前進程中載入的所有模組
r,d,e暫存器,記憶體的檢查和修改
!address顯示記憶體頁信息
S搜尋記憶體
!runaway檢查執行緒的CPU消耗
~切換目標執行緒
k,kb,kp,kv,kn檢查callstack
u反彙編
x查找符號的二進制地址
dds對應二進制地址的符號
2.1.5檢查程式資料的小例子
.frame在棧中切換以便檢查局部變數
dt格式化顯示資料
2.1.6用Windbg控制程式進行實時調試(LiveDebug)
WtWatchandTrace,跟蹤執行的強大命令
斷點和條件斷點(conditionbreakpoint),高效地控制觀測目標
偽暫存器,幫助保存調試的中間信息
StepOut的實現
2.1.7遠程調試(Remotedebug)
2.1.8如何通過Windbg命令行讓中文魔獸爭霸運行在英文系統上
2.1.9Dump檔案
2.1.10CDB、NTSD和重定向到KernelDebugging
2.1.11DebuggerExtension,擴展Windbg的功能
2.2讀懂機器的語言:彙編,CPU執行指令的最小單元
2.2.1需要用彙編來排錯的常見情況
案例分析:用彙編讀懂VC編譯器的最佳化
問題描述
我的分析
案例分析:VC2003編譯器的bug、debug模式正常,release模式會崩潰
例子程式
跟蹤彙編指令來分析
案例分析:臭名昭著的DLLHell如何導致ASP NET出現ServerUnavailable
2.2.2題外話和相關討論
Release比Debug快嗎
2.3理解作業系統對程式的反饋:異常(Exception)和通知(DebugEvent)
2.3.1異常(Exception)的方方面面和一篇字字珠璣的文章
案例分析:如何讓C++像C#一樣列印出函式調用棧(callstack)
2.3.2Adplus,抓取dump的方便工具
案例分析:華生醫生(Dr.Watson)在什麼情況下不能記錄Dump檔案
問題描述
背景知識
問題分析
新的做法
問題解決了,可是為什麼華生醫生(Dr.Watson)抓不到dump呢
2.3.3通知(DebugEvent)是作業系統跟調試器交流的一種方法
案例分析:VB6的版本問題
2.3.4題外話和相關討論
錯過第一現場後還從dump中分析出線索嗎
Adplus,天天都用的工具
未處理異常發生後的主動退出
如何調試UnhandledExceptionFilter
2.4平坦記憶體空間中的層次結構:Heap和Stack
2.4.1Heap是對平坦空間的高效管理和利用
2.4.2PageHeap,調試Heap問題的工具
簡單例子的多種情況
Heap上的記憶體泄漏和記憶體碎片
2.4.3Stackoverrun/corruption
2.4.4題外話和相關討論
PageHeap的/unaligned參數
Heaptrace,系統幫你記錄下每次Heap的操作
為何才分配了300MB記憶體,就報告Outofmemory
2.5找準排查問題的對應層次
2.5.1從C運行庫看層次
2.5.2簡單的_CRTDBG_MAP_ALLOC定義就可以讓記憶體泄漏無可遁形
2.5.3BSTRCache,建立在Heap之上的COM字元串記憶體管理
2.5.4題外話和相關討論
CRTDebugHeap一定對Debug有幫助嗎
C++中new操作符的尷尬
2.6理清多個執行緒對資源的競爭:同步和鎖
2.6.1句柄泄漏、死鎖和執行緒爭用,三個典型問題
句柄泄漏(HandleLeak)
死鎖(Deadlock)
執行緒爭用(contention)
2.6.2Windbg中的對應排錯
!handle檢查句柄信息
!htrace檢查操作句柄的歷史記錄
!cs列出CriticalSection的詳細信息
排查CriticalSectionleak(OrphanCriticalSection)
Invalidhandleexception
案例分析:ArrayList.Add的時候發生IndexOutOfRangeException
問題描述
這個異常不簡單
具體操作
結論
2.7調試和設計
2.7.1一位熱心朋友的提問
案例分析:反被聰明誤
第3章.NETFramework的原理和SOS調試——剖析CLR程式和CLR本身
3.1MetaData、JIT、GC和Exception的關鍵點
3.1.1MetaData(元資料)和引擎初始化
3.1.2JIT動態編譯
3.1.3GC記憶體管理
3.1.4ExceptionHandling異常處理
3.2用Windbg探索CLR的實現
3.2.1開源的CLR實現:Rotor
3.2.2對一個Helloworld的WinForm程式庖丁解牛
mscoree!_CorExeMainCLR引擎的入口
EEStartupHelper重要的引擎初始化函式
mscorwks!SystemDomain::ExecuteMainMethod執行託管代碼的入口
CallDescr/MakeJitWorkerJit引擎發動的地方
NtUserWaitMessage託管程式完成載入
gc_heap::allocate_more_space/GCHeap::GarbageCollect通過GC管理記憶體的分配和 釋放
AppDomain,ThreadPool,Exception,StackWalk,Security都是有趣的話題
3.3通過SOS快捷方便地調試託管程式
3.3.1CLR讓託管程式的調試變得非常簡單
3.3.2SOS的命令介紹
3.4用簡單的程式演示SOS的常見操作
3.4.1.loadSOS載入SOS到Windbg
3.4.2!dumpheap統計託管記憶體使用信息
3.4.3!do顯示託管對象的詳細信息
3.4.4!gcroot查找託管對象的引用關係
案例分析:ASP NETHighCPU和更多的CLR命令演示
!threads查看託管執行緒
!tp查看執行緒池和CPU占用率
!SyncBlk查看託管執行緒的lock
!ip2md映像記憶體地址到託管函式名
!savemodule保存模組到本地以便用reflector分析
著名的blog:Ifbrokenitis,fixityoushould
3.5題外話和相關討論
3.5.1ReleaseCOMObject釋放COM對象時候的兩難困境
3.5.2PInvoke應該Pin住記憶體防止崩潰
3.5.3Pin住記憶體又會導致記憶體碎片
3.5.4臭名昭著的mixedDLLloadingdeadlock
3.5.5有趣且有用的練習和更多的資料
第4章崩潰,性能和資源泄漏——分享一些經驗
4.1排錯開始前的準備工作
4.1.1用正確的態度對待問題
4.1.2用簡單的提問縮小排錯的範圍
4.1.3通過MPSREPORT獲取系統的詳細信息
4.1.4通過簡單的Dump分析獲取基本信息
4.2崩潰(Crash)
4.2.1崩潰的萬千種不同死相
4.2.2準確獲取Dump
Adplus:最容易上手的dump腳本
華生醫生(drWatson)
通過ImageFileExecutionOptions讓調試器隨目標程式一起啟動
COM+和ASP NET的dump獲取需要特殊配置
4.2.3crashdump中需要重點關注的信息
案例分析:VC程式的崩潰
問題描述
MessageBox嵌套調用
從原始碼中發現的疑點
從This指針找崩潰的根源
結論
4.2.4小結和更多的資源
4.2.5題外話和相關討論
HeapCorruption
StackCorruption
4.3性能(Performance)
4.3.1“你真牛,不如你再給我縮短10秒吧!”不是想要多快就能調到多快
4.3.2性能調優的步驟,CPU利用率是關鍵
4.3.3無所不知的性能監視器
使用性能監視器的基本步驟
重要的計數器
案例分析:部落格園的性能問題
案例分析:堵塞在SqlCommand.ExecuteReader上就一定在等sql嗎
問題背景
案例分析:堵塞在Assembly.Load上的deadlock
問題背景
案例分析:196個執行緒織成的一張網
問題背景
小結
4.3.4用Profiler精確定位性能瓶頸
案例分析:DataTable中foreach和forloop性能差了50%
問題背景
4.3.5題外話和相關討論
Taskmanager跟performancemonitor的差別
性能監視器的超級用法
C++跟C#到底誰快
沒有profiler怎么辦
4.4資源泄漏(ResourceLeak)
4.4.1資源泄漏分輕重緩急
4.4.2記憶體泄漏排錯的基本步驟
泄漏了什麼,誰分配的,為什麼無法釋放
定位泄漏記憶體的類型和增長趨勢
區分managedheapleak和nativeleak
案例分析:IE7的記憶體泄漏
問題描述
重現問題和基本分析
用傳統的Pageheap+UMDH找到問題根源
方便強大的IISDiagnostics工具
結論
分析IISDiag
4.4.3託管記憶體泄漏
案例分析:objectchain讓排錯簡單明了
問題背景
案例分析:一個bt的案例
碎片的其他原因
4.4.4句柄泄漏(HandleLeak)
4.4.5題外話和相關討論
GDILeak
Desktopheapissue
更多的資源