专栏首页bluesummer用Windbg来分析.Net程序的dump

用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:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.DLL

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

3.高内存占用示例

【读取文件代码】

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

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

【!gcroot address获取调用函数】

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用Token令牌维护微服务之间的通信安全的实现

    在微服务架构中,如果忽略服务的安全性,任由接口暴露在网络中,一旦遭受攻击后果是不可想象的、 保护微服务键安全的常见方案有:1.JWT令牌(token) 2.双向...

    蓝夏
  • NetCore在Docker中发布及运行 安装构建镜像启动容器DockerfileDocker-ComposeHttp连接请求过多问题

    之前写过一篇关于Docker的文章,回头看了一眼自己差点没有看明白...最近有时间又仔细研究了一遍(主要是生产环境真的要用到了...),顺便从0学习了一下Lin...

    蓝夏
  • ELK基础配置

    近期在研究日志系统的设计,感觉现在公司的子系统和接口太多了,日志看不过来,就想着有没有一种方法可以把各个程序的日志组合到一起。于是乎就搜到了ELK。开始对ELK...

    蓝夏
  • 构建企业级业务高可用的延时消息中

    扫库的方案一般体量不大时可以使用,当业务发展到一定规模后就不再适用。对IM消息重发秒级别的定时需求,只能增加扫库的频率,但过于频繁的扫库很可能会将数据库拖垮。显...

    孙玄@奈学教育
  • 文章测序数据下载碰到的问题的小总结(南京站学员分享)

    全国巡讲南京站过去还不到一周,学员们课后练习都很拼,微信群答疑对话一不留神就几百条了,爱学习的你是最美丽的!

    生信技能树
  • 芋道 Spring Boot MyBatis 入门(一)之 MyBatis + XML

    艿艿自己在 知识星球 中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章:

    芋道源码
  • 芋道 Spring Boot MyBatis 入门

    艿艿自己在 知识星球 中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章:

    芋道源码
  • HPILO管理经验二则

    hp ILO可以远程管理服务器,非常方便,但是hp ILO在web管理界面,没有重启的选项,如果需要重启ilo,可以使用以下方法: 一 服务器物理断电再加电,需...

    力哥聊运维与云计算
  • 14个实战案例带你了解Linux的‘sort’命令

    云豆贴心提醒,本文阅读时间7分钟 sort是什么 Sort是用于对单个或多个文本文件内容进行排序的Linux程序。 Sort命令以空格作为字段分隔符,将一行...

    小小科
  • python3:文件操作open() 方法超全详解

    python鱼霸霸

扫码关注云+社区

领取腾讯云代金券