[关闭]
@a604572782 2015-10-19T10:09:38.000000Z 字数 5024 阅读 3387

Windbg学习笔记1

windbg 代码分析 异常分析 性能调优


前言

当我们编写好的代码所生产的项目开始投产时,操作系统网络防火墙磁盘等诸多因素都会影响该程序的运行环境。即使在测试环境,该程序经受了各种各样的考验,由于投产环境多样化,也会导致该程序发生一些难以预料的异常(也包括在设计软件时考虑的不周全,或项目隐含一些难以查找的bug等因素引起的异常)

目的

为了尽快查找到程序发送异常的原因,降低给客户所造成的一系列麻烦,我们必想方设法来尽快解决这个问题。windbg就能满足我们的要求 ,他能够对栈进行跟踪监视本地程序调试代码

KD,CDB, NTSD and Windbg

Debugger概述

KD(Kernel Debugger):可以用于远程调试如蓝屏等操作系统问题,或开发驱动程序是也可用到。
CDB(Command-line debugger):这是一个控制台应用程序。通过它你可以显示并执行程序代码、设置断点、检查并改变内存中的值。它也可以分析二进制代码,显示程序集指令等。由于CDB可以通过地址或全局符号访问内存中的位置,你可以通过名字引用数据和质量而不是通过地址,我们可以更容易定位调试特定的代码块。
NTSD(NT debugger):这是一个CDB的变种,他有windows风格的UI,用户模式的调试器,你可以用它调试你的用户模式的应用程序。
windbg:封装了KD和NTSD,并有像模像样的UI,它可以同时用作用户模式和内核模式的调试。
VS debugger:它提供了比windbg更丰富的界面,使用了和KD和NTSD相同的引擎。

各debugger对比

windbg简介

WinDbg提供了命令行选项,它支持三种命令:
1. 常规命令(如k):用于调试过程。
2. 点命令(如.sympath):用于控制debugger。
3. 扩展命令(如!handle):这是自定义命令通过扩展的dll实现。

下载安装windbg

根据注意自己的操作系统选择相应的版本
64位下载
32位下载

PDB文件用途

PDB文件是生成的程序数据库文件,它并不包含说明或二进制代码,而是能让debugger读懂你编译好的程序。私有pdb包含了私有及共有符号,源代码行,类型,本地和全局信息。共有pdb不包含类型,本地和全局信息。

设置Symbols

Symbol下载
通过图形化界面操作,点击File->Symbol File Path输入
语法:SRV*downstream_store*http://msdl.microsoft.com/download/symbols
例如:srv*F:\windbg\symbols*http://msdl.microsoft.com/download/symbols

需要的Symbols会被下载到指定的路径。
当匹配PDB文件是,debugger会配如文件名、时间戳等信息,若已有symbol信息,你能看到你的调用堆栈函数名和它们的参数。如果这些二进制文件和pdb文件来自于你的程序,你还能获得关于私有函数、局部变量以及类型等信息。

源代码文件夹设置

在File->Source File Path 中设置源代码路径,在调试的过程中debugger会根据pdb调试过程中的行号匹配源代码。

安装PSSCor2

默认windbg是一个非托管代码[1]的调试工具,我们可以用一个SOS.dll的.net framework的扩展来让它可以调试托管代码[2]下载后是一个exe的文件选择安装路径会出现一个名为psscor2.zip的文件,将文件解压

选择相应版本的psscor2.dll复制到windbg根目录

创建转储文件

  1. 首先我们创建一个控制台小程序
  1. using System;
  2. namespace WindbgTest
  3. {
  4. class Program
  5. {
  6. static void Main(string[] args)
  7. {
  8. Console.WriteLine("Enter a message:");
  9. string input = Console.ReadLine();
  10. Data d = new Data
  11. {
  12. Message = input,
  13. CurrentDateTime = System.DateTime.Now
  14. };
  15. Console.WriteLine("You entered: " + d);
  16. }
  17. }
  18. public class Data
  19. {
  20. public string Message { get; set; }
  21. public DateTime CurrentDateTime { get; set; }
  22. public override string ToString()
  23. {
  24. Console.ReadLine();
  25. return string.Format("{0} at {1}", Message,CurrentDateTime.ToLongTimeString());
  26. }
  27. }
  28. }

这个段代码的功能是在输入一串字符按回车后显示这串字符并输出时间,但是我们加入了一个重载方法ToString(),其中有的Console.ReadLine();需要在输入两次回车才会显示,我们姑且认为这是一个bug。

  1. 运行程序,在任务管理器-右击-创建转储文件

  2. 加载转储文件
    • 打开windbg
    • 选择菜单,找到Open Crash Dump,选择刚才创建的转储文件

    • 显示模块列表(List Modules)
    • 在命令行中输入lm显示模块列表
  3. 加载PssCor2
    在命令行输入.load E:\开发工具\代码分析\psscor2\psscor2\amd64\psscor2.dll加载psscor2.dll
    为了确认加载成功,输入!help
  1. -------------------------------------------------------------------------------
  2. PSSCOR is a debugger extension DLL designed to aid in the debugging of managed
  3. programs. Functions are listed by category, then roughly in order of
  4. importance. Shortcut names for popular functions are listed in parenthesis.
  5. Type "!help <functionname>" for detailed info on that function.
  6. Object Inspection Examining code and stacks
  7. ----------------------------- -----------------------------
  8. DumpObj (do) Threads
  9. DumpArray (da) CLRStack
  10. DumpStackObjects (dso) IP2MD
  11. DumpAllExceptions (dae) BPMD
  12. DumpHeap U
  13. DumpVC DumpStack
  14. GCRoot EEStack
  15. ObjSize GCInfo
  16. FinalizeQueue EHInfo
  17. PrintException (pe) COMState
  18. TraverseHeap
  19. DumpField (df)
  20. DumpDynamicAssemblies (dda)
  21. GCRef
  22. DumpColumnNames (dcn)
  23. DumpRequestQueues
  24. DumpUMService
  25. Examining CLR data structures Diagnostic Utilities
  26. ----------------------------- -----------------------------
  27. DumpDomain VerifyHeap
  28. EEHeap DumpLog
  29. Name2EE FindAppDomain
  30. SyncBlk SaveModule
  31. DumpThreadConfig (dtc) SaveAllModules (sam)
  32. DumpMT GCHandles
  33. DumpClass GCHandleLeaks
  34. DumpMD VMMap
  35. Token2EE VMStat
  36. EEVersion ProcInfo
  37. DumpModule StopOnException (soe)
  38. ThreadPool MinidumpMode
  39. DumpHttpRuntime FindDebugTrue
  40. DumpIL FindDebugModules
  41. PrintDateTime Analysis
  42. DumpDataTables CLRUsage
  43. DumpAssembly CheckCurrentException (cce)
  44. RCWCleanupList CurrentExceptionName (cen)
  45. PrintIPAddress VerifyObj
  46. DumpHttpContext HeapStat
  47. ASPXPages GCWhere
  48. DumpASPNETCache (dac) ListNearObj (lno)
  49. DumpSig
  50. DumpMethodSig Other
  51. DumpRuntimeTypes -----------------------------
  52. ConvertVTDateToDate (cvtdd) FAQ
  53. ConvertTicksToDate (ctd)
  54. DumpRequestTable
  55. DumpHistoryTable
  56. DumpBuckets
  57. GetWorkItems
  58. DumpXmlDocument (dxd)
  59. DumpCollection (dc)
  60. Examining the GC history
  61. -----------------------------
  62. HistInit
  63. HistStats
  64. HistRoot
  65. HistObj
  66. HistObjFind
  67. HistClear
  1. 检查CLR堆栈
    输入!clrstack
  1. OS Thread Id: 0x354c (0)
  2. *** WARNING: Unable to verify checksum for mscorlib.ni.dll
  3. Child-SP RetAddr Call Site
  4. 000000000110e480 00007ff9b1a32569 DomainNeutralILStubClass.IL_STUB(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
  5. 000000000110e5a0 00007ff9b1a32452 System.IO.__ConsoleStream.ReadFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte[], Int32, Int32, Int32, Int32 ByRef)
  6. 000000000110e600 00007ff9b132082a System.IO.__ConsoleStream.Read(Byte[], Int32, Int32)
  7. 000000000110e660 00007ff9b1342a5a System.IO.StreamReader.ReadBuffer()
  8. 000000000110e6b0 00007ff9b1a3578f System.IO.StreamReader.ReadLine()
  9. 000000000110e700 00007ff952f00172 System.IO.TextReader+SyncTextReader.ReadLine()
  10. 000000000110e760 00007ff9b27a8f32 WindbgTest.Program.Main(System.String[])

参考文献

  1. Intro to WinDBG for .NET Developers
  2. Debug Tutorial Part Beginning Debugging Using CDB and NTSD
  3. Windows Debuggers: Part 1
  4. 托管代码与非托管代码的区别
  5. 5.

[1] 托管代码是一microsoft的中间语言(IL),他主要的作用是在.NET FRAMEWORK的公共语言运行库(CLR)执行代码前去编译源代码。
[2] 非托管代码就是在Visual Studio .NET 2002发布之前所创建的代码。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注