在哪些情况下,必须祭出一些复杂的调试器呢?大概有以下:

  1. 程序异常崩溃
  2. 程序内存泄露
  3. 程序挂起
  4. 程序消耗cpu 高

内存泄露有.Net Memory Profiler神器情况下,能比windbg更容易找到问题(当然限于托管代码内存泄露,许多非托管的还是比较难搞). 参考 使用.Net Memory Profiler 分析.Net程序内存泄露

同样CPU监控工具也有ANT Profiler 之类工具.

但总有一些BUG难以重现,特别是在非开发机器出现,此时抓个dump,可能更为方便.

下面就以一个demo为例简单使用windbg 分析程序崩溃和挂起这两种情况.


异常的最佳实践

按照我的经验,很多代码反映出的是---不知道什么是异常,什么时候抛异常,什么地方捕获异常,或有日志,连个堆栈信息都看不到.

如何编写正确的代码才是,这应当才是问题的根源.再方便的调试的工具,耗费的时间也依然很多.

我很长时间用不上windbg是因为.NET程序调试太为简单了.

关于使用异常推荐一篇文章

http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

windbg 安装

下载安装后要配置symbol path

抓Dump

程序崩溃时弹出错误对话框之类.只要进程还没退出,也就是我们说”没飞”

使用Windows任务管理器创建转储文件

Windows xp 好像没这功能,不过也没关系,可以使用Process Explorer

如何程序会”飞”,就得使用Windbg下的 ADPlus,监视某个进程,该进程崩溃时自动保存dump.

如:

adplus –quiet –crash –p 432 –o d:\debug

还有一种方法是,程序调用windows api自己生成dump.

以下以一个简单的Winform 程序演示:

试验1: 查找异常源

点击button 触发 btnException_Click 产生异常,抓dump

首先加载组件扩展,如果客户机器和你的机器不一样要copy 客户机器的.net framework 文件:

如:

>>.load  "E:\dmp\v4.0.30319\SOS.dll"

用!pe印详细异常信息:

0:000> !pe
Exception object: 017ed918
Exception type:   System.NullReferenceException
Message:          Object reference not set to an instance of an object.
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    0012EC78 002A0680 MemLeakProfileDemo!MemLeakProfileDemo.Form1.btnException_Click(System.Object, System.EventArgs)+0x10
    0012EC80 592A4507 System_Windows_Forms_ni!System.Windows.Forms.Control.OnClick(System.EventArgs)+0x7f
    0012EC94 592A6CA2 System_Windows_Forms_ni!System.Windows.Forms.Button.OnClick(System.EventArgs)+0xa2
    0012ECAC 5988A4E0 System_Windows_Forms_ni!System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)+0xac
    0012ECC8 59853E11 System_Windows_Forms_ni!System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)+0x2d1
    0012ED5C 59BF6A8F System_Windows_Forms_ni!System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)+0x8fc6ef
    0012EDB4 59BFE3F1 System_Windows_Forms_ni!System.Windows.Forms.ButtonBase.WndProc(System.Windows.Forms.Message ByRef)+0x8ec9dd
    0012EDF8 593119F8 System_Windows_Forms_ni!System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)+0x20
    0012EE04 592FA393 System_Windows_Forms_ni!System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)+0x13
    0012EE0C 592FA311 System_Windows_Forms_ni!System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)+0x31
    0012EE20 592FA256 System_Windows_Forms_ni!System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)+0x96

StackTraceString: <none>
HResult: 80004003

或者使用 !analyze -v 查看异常.有了堆栈信息很明了.

或者我们再使用 !dumpheap看了托管堆里有哪些信息,此时我只关心 MemLeakProfileDemo 命名空间的对象,也就是我自己代码使用的.或者使用!dso 打印当前堆栈的对象

0:000> !dumpheap -type MemLeakProfileDemo
Address       MT     Size
017cd058 00226410      352    
017d30e8 00226ba4       12    
017d310c 00226c34       12    
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
00226c34        1           12 MemLeakProfileDemo.FoolBrother
00226ba4        1           12 MemLeakProfileDemo.Fool
00226410        1          352 MemLeakProfileDemo.Form1
Total 3 objects

Fool 对象只有一个. MT (Method Table)是00226ba4 ,在上面可以看到它的地址是017d30e8

再用do 命令查看该地址的信息:

0:000> !do 017d30e8
Name:        MemLeakProfileDemo.Fool
MethodTable: 00226ba4
EEClass:     002b054c
Size:        12(0xc) bytes
File:        C:\Users\jhwang\Documents\Visual Studio 2010\Projects\MemLeakProfileDemo\MemLeakProfileDemo\bin\Release\MemLeakProfileDemo.exe
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
00212990  400000c        4 ...yte[], mscorlib]]  0 instance 017d30f4 list

再顺藤摸瓜查看 它的fields, list 需要用 !dumpvc来看

0:000> !dumpvc 00212990  400000c
Name:        System.Collections.Generic.IList`1[[System.Byte[], mscorlib]]
MethodTable: 00212990
EEClass:     631323c4
Size:        0(0x0) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:

这个列表是个空的.

试验2:查找线程挂起原因

点击另一个按钮触发btnHang_Click,然后关闭窗口,由于这个线程没有正确退出,进程不会退出,僵死在那里.抓dump然后打开.load sos后.

查看当前的线程:

0:000> !threads
ThreadCount:      3
UnstartedThread:  0
BackgroundThread: 2
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                   PreEmptive   GC Alloc                Lock
       ID  OSID ThreadOBJ    State GC           Context       Domain   Count APT Exception
   0    1  1e68 003fe898   2016220 Enabled  019dd3f0:019ddfe8 003f8410     0 STA
   2    2  11e4 00409cc8      b220 Enabled  00000000:00000000 003f8410     0 MTA (Finalizer)
   5    3  14b4 00445430   200b020 Enabled  019c2014:019c3fe8 003f8410     0 MTA

STA 和MTA是个啥,我也不清楚.正常 program.cs 里常有这个

     [STAThread]         static void Main()

这个估计不是我们想看的,第二个MTA线程,看样子是GC之类的,那肯定是第三个了.切换到这个线程并看堆栈

0:003> ~5s
eax=001363c8 ebx=00000001 ecx=000003e8 edx=019c1458 esi=0455ef50 edi=00000000
eip=776b7094 esp=0455ef0c ebp=0455ef74 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!KiFastSystemCallRet:
776b7094 c3              ret
0:005> !clrstack
OS Thread Id: 0x14b4 (5)
Child SP IP       Call Site
0455f034 776b7094 [HelperMethodFrame: 0455f034] System.Threading.Thread.SleepInternal(Int32)
0455f080 001a06ed MemLeakProfileDemo.Form1.DoWork() [C:\Users\jhwang\Documents\Visual Studio 2010\Projects\MemLeakProfileDemo\MemLeakProfileDemo\Form1.cs @ 80]
0455f088 6338b30b System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
0455f098 63318004 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
0455f0bc 63317f44 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
0455f0d8 6338b298 System.Threading.ThreadHelper.ThreadStart()
0455f2fc 69a1219b [GCFrame: 0455f2fc]
0455f5c0 69a1219b [DebuggerU2MCatchHandlerFrame: 0455f5c0]

对照代码.一切了然.

小结: sos本身的命令很多,用过的也不多,除了sos.dll 这个扩展以外,网上还有sosex,PssCor4 等调试扩展.稍微了解一点windbg也能给我们的生活easy一点.

source code: downoad

转载于:https://www.cnblogs.com/solo/archive/2012/09/20/2695426.html

Windbg 离线调试.Net 程序入门相关推荐

  1. WinDbg调试.NET程序入门

    俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dum ...

  2. 配置Editplus调试PHP程序入门教程

    之前介绍了PHP开发工具zend studio7入门使用教程,zend studio的使用其实蛮耗费内存的,针对PHP入门学习者,今天和大家分享如何配置Editplus来调试PHP程序,Editplu ...

  3. windbg+psscor2调试.net程序

    加载clr调试插件  .load psscor2 设置调试符号文件地址,一般指向网站的bin目录下,里面每个Dll会有一个 PDB文件 .sympath D:\website\pdhbj\Pdhb.S ...

  4. WinDBG调试dNet程序总结

    WinDBG工具简介 http://www.cnblogs.com/mashuping/archive/2009/03/28/1424168.html 对于一般的程序不需要使用WinDBG工具去调试, ...

  5. [系统安全] Windbg Preview调试记录

    本文为笔者从零基础学习系统安全相关内容的笔记,如果您对系统安全.逆向分析等内容感兴趣或者想要了解一些内容,欢迎关注.本系列文章将会随着笔者在未来三年的读研过程中持续更新. 前文链接 [系统安全] PE ...

  6. 编写windbg调试器扩展 入门篇1

    我博客的左侧专栏曾经转过windows下编写调试器的一系列文章,这类文章是从零打造调试器,而这篇文章是介绍如何为windbg编写调试器扩展命令. 0.前言 windbg的命令有很多,其中以" ...

  7. 使用WinDbg调试SQL Server——入门

    这篇文章我想探究下SQL Server里完全不同的领域:如果使用WinDbg(来自针对Windows的调试工具)调试SQL Server.在我们进入枯涩细节之前,我想详细解释下为什么选择这样晦涩的话题 ...

  8. 小程序真机调试访问不了接口_小程序入门

    之前写了一个去水印的小程序,详情可查看「短视频去水印工具小程序版-去水印Pro版」一文,我个人对小程序也是从完全陌生到入门阶段,这篇文章就把入门的过程和遇到的问题记录一下. 一.小程序注册 想要开发小 ...

  9. 首次使用Windbg调试dNet程序

    dNet程序反编译后是IL汇编,是虚拟机汇编语言:是不能直接用WinDBG调试的:模糊记得,windbg需要加载名为SOS的扩展,才能调试dNet程序:下面来试一下: windbg设置好符号路径: V ...

最新文章

  1. 基于 K8S 构建数据中心操作系统
  2. java正则表达式 1,Java正则表达式学习(1)
  3. linux 挂载 nfs 权限,linux – 如何允许写入已挂载的NFS分区
  4. 13.SpringMVC和Spring集成(一) 14.SpringMVC和Spring集成(二)
  5. vue新版本和旧版本关闭eslint总结
  6. 集训队脱单大法:这是一道只能由学姐我自己出数据的水题
  7. 《嵌入式系统可靠性设计技术及案例解析》读书笔记(五)
  8. 云水画中人,独立一江秋
  9. 【深度学习】Win10安装TensorFlow_gpu(避坑必看)
  10. 嵌入式算法-傅里叶变换算法
  11. @scheduled注解配置时间_Spring Boot中使用@Scheduled创建定时任务
  12. docker+elasticsearch的安装
  13. JavaScript之浏览器大战
  14. c语言函数实现顺序线性表,数据结构C语言实现——顺序线性表SqList
  15. word文档左下方竟然出现无法删除的小横线???
  16. maya扇子动画_MAYA制作动画的十大原理!
  17. mysql数据库取奇数行数据_查询数据库中的奇数行和偶数行
  18. ev3编程变量模块_英文视频教学翻译-机器人ev3编程学习的第二十讲:举例讲解数据变量模块编...
  19. 3DMAX快速入门 界面介绍【上】
  20. 机器学习:什么是困惑度?从信息熵和交叉熵谈起

热门文章

  1. java pojo生成_生成代码的代码 之 POJO生成器
  2. java mongocollection_MongoDb完结笔记-与java结合
  3. pythoninformation leakage_GitHub - MrFk/GSIL: Github Sensitive Information Leakage(Github敏感信息泄露)...
  4. ueditor添加下拉事件_Excel中最智能的三级下拉菜单!
  5. python网络编程linux清华_Python网络编程篇之socket
  6. 服务器虚拟化平台 可信云认证,100%满足规范,华为云Stack首批通过可信云虚拟化云平台最高等级认证...
  7. 一键清理Quartus工程编译垃圾
  8. 总结2-深度学习网络搭建学习
  9. 基于QItemDelegate的例子2 trackeEditorDelegate
  10. Python机器学习(sklearn)——分类模型评估与调参总结(下)