使用Windbg调试.Net应用程序 [转]

1. 解决线上.NET应用程序的如下问题:

  • 崩溃
  • CPU高
  • 程序异常
  • 程序Hang死

2. 安装WinDbg:

http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx

3. 配置WinDbg:

运行WinDbg->菜单->File->Symbol File Path->按照下面的方法设置_NT_SYMBOL_PATH变量:
在弹出的框中输入“C:\MyCodesSymbols;
SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照这样设
置,WinDbg将先从本地文件夹C:\MyCodesSymbols中查找Symbol,如果找不到,则自动从MS的Symbol
Server上下载Symbols)。另一种做法是从这个Symbol下载地址中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下载相应操作系统所需要的完整的Symbol安装包,并进行安装,

4. 利用WinDbg里的adplus来获取dump文件。

 Dump文件是进程的内存镜像。可以把程序的执行状态通过调试器保存到dump文件中。

在WinDbg安装目录里可以找到adplus.exe,把他拖入到命令行中,然后用命令

adplus.exe -hang -pn test.exe -o c:\dumps  // 抓取当前的dump文件

adplus.exe -crash -pn test.exe -o c:\dumps  // 监听应用程序,当crash时,获取dump文件

命令-pn :应用程序名,-p:应用程序pid,-odump文件输出路径

5. 利用WinDbg加载dump文件加载调试器

运行WinDbg->菜单->File->Open Cresh dump 打开dump文件,并加载.net调试器

.loadby sos mscorwks  .Net 3.5版本及以下

.loadby sos clr  .Net 4.0

如果服务器的.Net版本与本机不匹配需要服务器版本的mscordacwks.dll文件

并设置.sympath = mscordacwks_x86_x86_2.0.50727.3607.dl

6. WinDbg的基本命令

help  sos指令帮助

!threads  显示所有线程

!dumpheap  显示托管堆的信息

!clrstack  显示调用栈

!dumpobj  显示一个对象的内容

!dumparray  显示数组

!syncblk  显示同步块

!runaway  显示线程cpu时间

!gcroot  跟踪对象内存引用

!pe  打印异常

7. WinDbg的使用

当我在Form中执行这段代码:

[csharp] view plaincopyprint?

  1. public Form1(){
  2. InitializeComponent();
  3. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
  4. }
  5. private void UnhandledExceptionProc(object obj){
  6. try {
  7. throw new Exception("1st chance");
  8. } catch (Exception) {
  9. MessageBox.Show("after 1st");
  10. }
  11. int d = 0;
  12. int n = 1 / d;
  13. }

并活动dump文件


用windbg打开dump文件后输入-pe:可以看到问题的所在。

异常如此重要,所以操
作系统提供了对应的调试功能,可以使用调试器来检视异常。异常发生后,操作系统在调用用户态程序的异常处理函数前,会检查当前用户态程序是否有调试器加
载。如果有,那么操作系统会首先把异常信息发送给调试器,让调试器有观察异常的第一次机会,所以也叫做first chance
exception,调试器处理完毕后,操作系统才让用户态程序来处理。

如果用户态程序处理了这个异常,就没调试器什么事了。否则,程序在unhandled exception崩溃前,操作系统会给调试器第二次观察异常的机会,所以也叫做second chance exception。

《Windows用户态程序高效排错》

分析以下代码:可以看出DummyObject 会占用很多内存,甚至导致内存溢出

[csharp] view plaincopyprint?

  1. private void MemeryLeakProc(object obj)
  2. {
  3. while (true) {
  4. for (int i = 0; i < 100 * 1024; i++) {
  5. DummyObject o = new DummyObject();
  6. list.Add(o);
  7. }
  8. Thread.Sleep(1000);
  9. }
  10. }

windbg命令:!dumpheap –stat 统计堆栈内存

线程Hang住的常见原因

-线程池或工作线程集中在某个耗时的工作当中,或者被其他线程锁住

核心问题,找到被hang住的线程

!threads

~*e!clrstack

!synblk

[csharp] view plaincopyprint?

  1. lock (syncRoot) {
  2. int tp;
  3. int io;
  4. //ThreadPool.GetMaxThreads(out tp, out io);
  5. for (int i = 0; i < 100; i++) {
  6. Thread hangThread = new Thread(HangProc);
  7. hangThread.Start();
  8. }
  9. MessageBox.Show("Press to release lock");
  10. }

[csharp] view plaincopyprint?

  1. private void HangProc(object obj)
  2. {
  3. lock (syncRoot) {
  4. n = 0;
  5. }
  6. }

CPU高

-如果与业务量没有提升,有线程在长时间的处理

核心问题,找到占用CPU的线程

!runaway

~*e!clrstack

线程死锁出现的情况:

两个锁A,B,

一个线程已经拿到锁A,申请锁B,

另一个线程已经拿到锁B,申请锁A

核心问题:找到锁定的线程

!threads

!syncblk

~*e!clrstack

•两条指令可以解决大部分的问题

•!dumpheap –stat

•~*e!clrstack

http://blog.csdn.net/kntao/article/details/7086616

时间: 2024-10-07 04:50:31

使用Windbg调试.Net应用程序 [转]的相关文章

【转】WinDbg调试器:启动程序时自动连接调试器方法

当我们调试服务进程或子进程时,无法直接用调试加载进程的方式启动,此时需要在启动程序时自动连接调试器方法: 第一步:注册表展开到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options路径下: 第二步:在Image File Execution Options上鼠标右键,新建"项",项名为你要调试的程序,比如 test.exe: 第三步:在项名上,右键,新建字符

WinDbg 调试.net程序

WinDbg支持以下三种类型的命令: ·        常规命令,用来调试进程 ·        点命令,用来控制调试器 ·        扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dll提供这些命令 PDB文件 PDB文件是由链接器产生的程序数据库文件.私有PDB文件包含私有和公有符号,源代码行,类型,本地和全局变量信息.公有PDB文件不包含类型,本地变量和源代码行信息,且只包含共有成员的调试信息. Dump文件 利用Dump工具,你可以获得进程的快照信息.一个mini-dump

调试技巧 —— 如何利用windbg + dump + map分析程序异常

调试技巧 —— 如何利用windbg + dump + map分析程序异常 逗比汪星人2011-09-04上传 调试技巧 —— 如何利用windbg + dump + map分析程序异常 http://blog.csdn.net/wangningyu/article/details/6748138 http://download.csdn.net/detail/wangningyu/3575167

WinDbg调试.NET程序入门

俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dump文件,但是只看到键盘 “啪啪啪”,得到了结果,却不是很清楚WinDbg神奇具体如何使用的.结果,第二天,性能问题又来了,总不能每次劳烦大神驾到,所以不得不自己开始学习WinDbg,这里记录一个入门过程. 1,首先,下载并安装WinDbg程序 从下面的地址打开:https://msdn.micros

WinDbg调试CPU占用高的问题 试验+实战 《第七篇》

一.High CPU试验 1.示例代码 static void Main(string[] args) { Console.Clear(); Console.WriteLine("到命令行下,切换到windbg目录,执行adplus -hang -pn highcpu.exe -o c:\\dumps"); Console.WriteLine("如果要停止,按Ctrl+C结束程序"); Console.WriteLine("================

转:windbg调试堆

转:http://www.cnblogs.com/dsky/archive/2013/05/15/3079363.html windbg调试HEAP HEAP的概念 堆栈堆栈,在操作系统内存中有两种存储空间,一个是堆,一个是栈.堆主要用于存储用户动态分配的变量,而栈呢,则是存储我们程序过程中的临时变量.当然栈的作用远不止用作存储变量,但这不是我们这篇文章的讨论内容. 堆(HEAP)的分配,使用,回收都是通过微软的API来管理的,最常见的API是malloc和new.在往底层走一点呢,这两个函数都

调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置

调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置 调试SQLSERVER (一)生成dump文件的方法调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令 大家知道在Windows里面,调试可以分为两个领域: 1.内核态调试 2.用户态调试 一般的程序都是运行在用户态,包括SQLSERVER,SQLServer 会依赖于操作系统的Win32/Win64 API去调用I/O或者其他他需要的服务 用户态程序调试和内核态程序调试是不太一样的,即使

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令 调试SQLSERVER (一)生成dump文件的方法调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置 windbg命令分为标准命令.元命令.扩展命令 标准命令提供最基本的调试功能,不区分大小写.如:bp g dt dv k等 元命令提供标准命令没有提供的功能,也内建在调试引擎中,以.开头.如.sympath .reload等 扩展命令用于扩展某一方面的调试功能,实现在动态加载的扩展模块中

Windbg调试命令详解

发表于2013 年 8 月 23 日由张佩 转载注明>> [作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd.exe.kd.exe和Windbg.exe.其中cdb.exe和ntsd.exe只能调试用户程序,Kd.exe主要用于内核调试,有时候也用于用户态调试,上述三者的一个共同特点是,都只有控制台界面,以命令行形式工作. Windbg.exe在