zoukankan      html  css  js  c++  java
  • 用Windbg来分析.Net程序的dump

    介绍

    1. 什么是Windbg

    • WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。
    • WinDbg是微软很重要的诊断调试工具: 可以查看源代码、设置断点、查看变量, 查看调用堆栈及内存情况。
    • Dump文件是进程的内存镜像, 可以把程序的执行状态通过调试器保存到dump文件中

    2. Windbg可以解决以下问题

    ◆ 内存高
    ◆ CPU高
    ◆ 程序异常
    ◆ 程序Hang死

    3. 使用windbg进行调试分析的两种方式

    • 使用windbg调试器attach到需要调试的进程。(会暂停进程的运行)
    • 抓取进程的dump文件,使用windbg分析dump

    一.准备

    1.下载

    官网地址:
    https://developer.microsoft.com/zh-cn/windows/hardware/windows-driver-kit
    选择对应的工具包下载

    2.安装

    1. 下载之后点击安装,可选择安装的工具,我们只选择windbg就可以。安装之后在debuggers文件夹下选择32位或64位程序运行

    1. 打开windbg之后,需要设置symbol path,可以按快捷键Ctrl+S。把下面的路径粘贴进去保存。系统进行dump解析等操作的时候会自动下载需要的符号表
      srvc:symcachehttp://msdl.microsoft.com/download/symbols;c:symcache;

    3.抓取dump

    1. 通过procdump获取

    下载地址:https://technet.microsoft.com/en-us/sysinternals/dd996900

    下载之后为压缩包,将文件解压。通过dos命令来生成dump文件。下面为一条语句为示例

    procdump -ma -c 0 -s 3 -n 2 sqlservr.exe -o E:dumps

    这条语句的意思为:当sqkservr.exe这个进程运行时间cpu的占用超过0%,时间超过3秒,则在E:dumps下生成一个dump文件。一直到生成2个为止。下面为命令介绍

    • -ma 生成full dump, 即包括进程的所有内存. 默认的dump格式包括线程和句柄信息.
    • -c 在CPU使用率到达这个阀值的时候, 生成dump文件.
    • -s CPU阀值必须持续多少秒才抓取dump文件.
    • -n 在该工具退出之前要抓取多少个dump文件.
    • -o dump文件保存目录.
    • Sqlservr.exe可替换为进程的ID

    下图为运行示例(sqlserver等操作需要cmd以管理员权限打开)

    2. 任务管理器抓取

    可在任务管理器进程右键进程,点击创建转储文件,系统会自动抓取和保存,保存完成会弹出对话框提示保存路径

    二.解析

    1.解析dump文件

    通过windbg的菜单,File—>Open Crash Dump选择dump文件打开。打开成功界面如下图所示:

    2.命令

    1.基本命令

    • ? 获取命令提示
    • D 查看内存信息
    • K 观察栈
    • ~ 显示和控制线程 ~number s number为线程id 如:~1s为获取1号线程的上下文
    • Q 退出
    • !runaway 查看线程占用cpu时间,可看出哪个线程占用时间最高(所有线程)
    • .dump /ma E:/dumps/myapp.dmp 抓取dump

    2.元命令

    • .help 获取命令提示
    • .cls 清屏
    • .ttime 查看线程占用cpu时间,可看出哪个线程占用时间最高(当前线程)

    3..扩展命令

    • . chain 获取命令集列表。在已经加载的动态链接库中。
    • .load/.unload 加载/卸载命令模块
    • **!模块名.help **查看某个扩展库中包含的扩展命令

    4..Net程序相关命令

    基本

    • !peb或!dlls 列出进程已经加载的dll
    • **!threadpool ** 查看当前CPU状况 线程数等等
    • !dumpheap –stat 统计堆信息
    • !Threads 所有托管线程 -special Crl创建的线程
    • !clrstack 看看这个线程再干嘛 执行那些方法
    • !clrstack –p addr addr:具体方法的参数值地址
    • !do 地址 查看参数值
    • !analyze –v 显示分析的详细信息
    • .reload /i /f 强制重新加载pdb

    内存调试

    • **!eeheap –gc ** 获取gc中内存信息
    • !eeheap –loader Loader 堆信息
    • !dumpheap –stat 统计GC堆的信息,统计GC堆上存活的对象
    • !dumpheap -mt <> 查看该地址上的对象
    • !gcroot <<对象地址>> 查看对象根
    • **!dumpheap -type <<System.String >> ** 查看string类型在堆中的信息
    • !helproot -查看gcroot的帮助

    在解析.Net程序时首先要加载运行环境framework版本对应的SOS.DLL

    .load C:WindowsMicrosoft.NETFramework64v4.0.30319SOS.DLL

    这里只是写一些比较常用的命令,想要详细了解更多命令了以到官网查看

    3.高内存占用示例

    【读取文件代码】

    【在代码执行过程中抓取dump文件打开,并加载sos.dll】


    【运行!dumpheap –stat获取最高内存占用的地址】

    【!gcroot address获取调用函数】

    最终,我们找到了高内存的调用入口!
    当然如果gc堆上的占用内存较高的对象是自定义的类,那么就可以直接查看相关的调用函数来分析可能的问题了

  • 相关阅读:
    中文词频统计及词云制作
    字符串操作练习:星座、凯撒密码、99乘法表、词频统计预处理
    python第二节课
    Python第一节课
    了解大数据
    pcb结构定义
    一个完整的大作业
    中文词频统计及词云制作
    字符串操作练习:星座、凯撒密码、99乘法表、词频统计预处理
    Python输入输出练习
  • 原文地址:https://www.cnblogs.com/bluesummer/p/8125013.html
Copyright © 2011-2022 走看看