1.背景

最近由于线上的程序发生了死锁,而且重现的概率很低,正好客户反馈一个任务超时了,登上线上环境发现有一个“僵尸”进程,占用内存不波动,cpu仍在占用,

那么用创建转储文件,用windbg调试吧。

2.准备
2.1.下载windbg
需要下载Windows 调试工具 (WinDbg):Windows 10 SDK,安装时候根据需要,可以只安装Debugging Tools For Windows,即windbg;
如果已下载并安装Windows 10 SDK,而没有安装Windbg,那么在控制面板》程序》Windows Software Development Kit》右键选择更改》change》勾选Debugging Tools For Windows》安装

2.2.相关知识

可参考官方文章:

Windows 调试入门

WinDbg 入门(内核模式)

WinDbg 入门(用户模式)

使用 WinDbg 进行调试

后文还会贴出一些有参考价值的博客文章;

2.3.所需文件
2.3.1.DMP文件
.dump(创建转储文件)
可以为进程创建转储文件(dmp),既可以在任务有管理中选中进程》右键》创建转储文件;
也可以用windbg附加到进程(附加后会让程序暂停,注意这时候要用windbg的g(go)或者step out、step over等让程序继续运行,运行完再创建dmp文件)让程序运行到出错位置后,windbg会发现异常并中断,然后输入:.dump /f e:dump/XXXX.dmp,生成全信息的dmp文件;
当然转储文件有多种,详细参考官方文章;
2.3.2.符号文件
需要符号文件,就像VS里面设置符号加载,这里可以包含调试目标程序的符号文件(pdb)路径、microsoft符号文件及符号缓存目录;借助符号文件和源代码可以准确的定位堆栈位置及异常位置;

在windbg中符号路径设置里注意事项:SRV*e:\symbols*http://msdl.microsoft.com/download/symbols;C:\Users\heuwz\source\repos\x64\Release

其中*e:\symbols*为符号缓存目录(就像VS中设置符号缓存目录),http://msdl.microsoft.com/download/symbols为microsoft符号服务器,C:\Users\heuwz\source\repos\x64\Release为目标程序符号(pdb文件)所在目录;

在Windbg中Ctrl+s快捷键可以打开设置符号路径面板;

设置时可以合理的利用面板中的Browser按钮选择本地目录,这样可以最大化的避免手动输入可能带来的格式问题;

2.3.3.源代码文件
需要结合符号文件和源代码文件来分析确定堆栈位置、异常位置等再源代码中的位置,从而提供更准确的调试信息,供使用者进一步的分析问题;

设置源代码文件路径(ctrl+p),仅仅是相关的代码文件就可;

同样可以合理的利用面板中的Browser按钮选择本地目录,这样可以最大化的避免手动输入可能带来的格式问题;

3.开始
为方便说明,下面以一个例子进行讲解,

3.1.准备程序
代码(会引发异常)如下

#include "pch.h"
#include <iostream>
#include <thread>
#include <windows.h>using namespace std;class TestClass
{
//  该类仅做示例用,有很多不规范的地方,比如构造函数,析构函数,赋值重载,成员字段公开等问题
//  读者可批判的看待
public:int NTest;};int main()
{std::cout << "Hello World!\n";Sleep(50000);TestClass* testPtr = 0;//  出问题了testPtr->NTest = 3;std::cout << testPtr->NTest << std::endl;}

编译生成可执行程序;

3.3.调试分析问题

让用户把生成的DMP文件发给自己,然后自己继续用Windbg+DMP文件+符号+源代码文件来调试分析问题;

(1)亲测,可以先设置源码路径和符号路径,再去打开dmp文件,会自动定位到异常位置;
(2)亲测,也可以先打开dmp文件;再设置符号路径(ctrl+s),注意设置完后勾选reload;再设置源代码文件路径(ctrl+p),仅仅是相关的代码文件就可,也会自动定位到异常位置;

(3)符号路径设置里注意事项:SRV*e:\symbols*http://msdl.microsoft.com/download/symbols;C:\Users\heuwz\source\repos\x64\Release
其中SRV后面**中间的路径为符号缓存路径,会将通过后面符号器下载的符号缓存到这个位置;后面紧跟的是微软符号服务器;再后面是调试的dmp文件对应exe的符号路径;
(4)设置符号路径和代码文件路径时可以用browser按钮来设置,这样会避免格式出错问题;

当然如果是死锁问题,那么需要输入命令:!analyze -v -hang

回车,等待分析完,然后结合其他命令,如,

~*kb:显示当前进程所有线程的堆栈;

~1kb:显示一号线程堆栈;

d:命令显示esp寄存器指向的内存;

!cs -s:如果可能的话,显示每个临界区的初始堆栈回溯;

!cs -l:仅显示锁定的临界区;

!locks:查看所有的线程占用的锁情况;

~~[ce84]s:切换到线程ce84;

kb:查看该线程的函数调用栈情况;

定位各线程的堆栈和对应在代码中的位置,然后分析产生死锁的原因;

3.4.其他
可以用windbg分析dmp,也可以直接用vs打开dmp文件来分析,
实测过程中,
(1)用windows管理器的“创建转储文件”生成的dmp,既可以用vs打开,也可以用windbg打开;
(2)用windbg附加到进程的方式(附加后会让程序暂停,注意这时候要用windbg的g(go)或者step out、step over等让程序继续运行,运行完再创建dmp文件)
让程序运行到出错位置后,windbg会发现异常并中断,然后输入:.dump /f e:dump/XXXX.dmp,来生成全信息的dmp文件;
这种方式的dmp文件可以用windbg分析,但用vs打开会提示版本过旧,无法打开;原因可能如下使用 Visual Studio 打开转储文件

4.参考资料
除了官方文章外,学习过程中还参考了如下文章,

4.1.参考较多的文章
1、使用windbg抓取崩溃文件和分析的过程
https://blog.csdn.net/breaksoftware/article/details/13989025

备注:实操性强;

2、winDbg定位异常崩溃和线程死锁三步骤
https://blog.csdn.net/lv_yjie2011/article/details/41706231
备注:这一篇博客属于导航类的博客,导航到了其他博客,也十分有帮助;

3、WinDbg非常简单的调试dmp文件
https://blog.csdn.net/u010340160/article/details/84452408
备注:这篇博客说的没错,很简单,但对于新手来说太简单了,很多相关的概念和原理没说,只是一个流程,照着做;
4、记录windbg调试临界区死锁问题
https://www.cnblogs.com/pro-love/p/10936029.html
备注:实操性强,有帮助;
5、windbg解决线程死锁
https://blog.csdn.net/woshiyuanlei/article/details/47657313
备注:介绍了丰富的windbg命令,根据需要可以参考;

4.2.其他参考文章
1、17.windbg-!cs、~~[TID](经典死锁)
https://blog.csdn.net/hgy413/article/details/7572097
2、Windbg中查看函数参数
https://blog.csdn.net/wonderdaydream/article/details/73554644
3、Windbg找出死锁
https://www.cnblogs.com/leo_wl/p/3406212.html
4、windbg的使用四(Windbg检查死锁 )
https://blog.csdn.net/chenchong_219/article/details/25081379
5、windbg调试死锁,好迷茫,请教
https://bbs.csdn.net/topics/390740501?page=1
6、win10ltsc版基本信息及优点介绍
http://www.somode.com/softjc/9504.html
7、VC2005中fopen的ccs=UNICODE实测<zt> + UTF8 如何转变为 ansi
https://www.cnblogs.com/slash/archive/2010/06/27/1766225.html
8、多线程死锁调试小技巧
https://www.cnblogs.com/zhuyp1015/p/3618863.html
9、Detecting reflective DLL loading with Windows Defender ATP
https://www.microsoft.com/security/blog/2017/11/13/detecting-reflective-dll-loading-with-windows-defender-atp/
10、Application Control for Windows
https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/windows-defender-application-control
11、What's new in Windows 10 Enterprise 2019 LTSC
https://docs.microsoft.com/en-us/windows/whats-new/ltsc/whats-new-windows-10-2019
12、windbg调试std::mutex死锁问题!!!
https://blog.csdn.net/jiangdong2007/article/details/89513524

可以再研究下符号服务器的搭建,这样方便给客户调试问题;

5.结论
很多时候,用户使用程序出现问题了 或者 线上机器运行程序出现问题了,不方便在用户电脑上/线上机器调试问题,如果再在用户电脑/线上机器上安装VS,拉取源代码仓库,那就更难可行并且问题风险多多,操作复杂;

那么这时候可以让用户转储为DMP文件,并提供程序的版本号等信息,然后自己用Windbg或者VS调试分析问题,当然这样又会引发两个怎么让工作效率更高更可靠的问题,

1、用户使用程序崩溃了要手动联系开发方并手动生成DMP文件发发给开发方吗?

2、符号文件该怎么管理?用户告诉你了版本号,你还能找到符号文件吗?

当然这两个问题,大公司都有解决方案;

winDebug 调试相关推荐

  1. Windebug的一个缺点

    最近碰到一些难fix的bug,开始借助Windebug调试应用程序,发现在使用windebug时有一个缺点.网上好多文章都提到可以通过配置环境_NT_SYMBOL_PATH= SRV*C:\My Lo ...

  2. 生产环境(基于docker)故障排除? 有感于博客园三番五次翻车

    前言 如题,有感于博客园最近多次翻车,感觉像胡子眉毛一把抓, 定位不了生产环境的问题. 抛开流程问题,思考在生产环境中如何做故障排除, 发现博客园里面这方面的文章比较少. .Net 本身是提供了sos ...

  3. python 执行shellcode_执行shellcode的方法

    前言 进程内存布局 需要理解的第一个概念是,整个虚拟内存空间分为两个相关部分:为用户进程保留的虚拟内存空间(用户空间)和为系统进程保留的虚拟内存空间(内核空间),如下所示 当处理器读写内存位置时,它使 ...

  4. WinDebug快速使用及调试注意事项

    参考文献: http://www.cnblogs.com/killmyday/archive/2010/03/14/1685331.html WinDbg是微软发布的一款强大的源码级调试工具,支持用户 ...

  5. 附上windebug常用调试命令

    一.基础命令 程序重在编程思维,难在程序调试,写出了程序还不行,还必须进行调试,证明结果. WinDbg是微软开发的一款强大无比的调试器.利用它我们可以进行内核双机调试. 在调试程序之前我们要掌握如何 ...

  6. Windebug双机调试环境搭建2020-10-12

    主要参考 这两篇文章 https://www.cnblogs.com/fanling999/p/3920202.html https://www.cnblogs.com/witty/archive/2 ...

  7. WinDebug双机调试

    Windows 7 创建Debug 启动项: bcdedit /copy {current} /d "Kernel Debug" bcdedit /debug {current} ...

  8. WinDebug 配置 调试 设置

    今天初次使用WINDBG,遇到了两个问题,最后解决了.此处和大家一起分享一下: 1) WARNING: Non-directory path 我在符号路径里都填加了还是遇到,这时我发现其实只要添加路径 ...

  9. 双机调试和windbg的命令

    各位大牛以及和我一样还是菜鸟的朋友们,大家好,今天在调试驱动程序时,由于要做双机调试,所以顺便再论坛发给以后需要的朋友,相对网上其他教程我的这个 算是比较详细了,因为我是看了网上很多相关文章,他们多多 ...

最新文章

  1. php zblog 侧边栏样式_zblogphp版如何实现导航栏下拉框
  2. 如何更改Twitter Bootstrap模式框的默认宽度?
  3. 电脑打印机共享,打印机共享
  4. JVM源码阅读-本地库加载流程和原理
  5. java-final关键字
  6. f60gen command
  7. dart系列之:如丝滑般柔顺,操作文件和目录
  8. objectdatasouce的温故
  9. Unity AI副总裁Danny Lange:如何用AI助推游戏行业?
  10. SylixOS 内存管理源代码分析--vmmMalloc.c
  11. mips的旁路_低功耗设计二之Bypassing(旁路)
  12. chmod和chown命令的用法
  13. bmfont-instructions
  14. 直播svga礼物应该如何设计,让用户更加青睐
  15. JavaScript设计模式——观察者模式
  16. ARM ADS中的AXD 调试经验集锦
  17. 媒体聚焦:西电卡门——12月24日更新
  18. 【毕设教程】OLED屏幕介绍与使用
  19. 《迅雷链精品课》第八课:迅雷链多链结构
  20. 【DB】数据库面试笔试题库及详解(小麦苗DBA宝典出品)--数据库运维宝典

热门文章

  1. 使用CCS调试CC3200芯片GPIO接口应用----流水灯程序
  2. [转载]转录组测序分析中cufflinks的使用及问题
  3. fhq——treap
  4. 8086CPU内部结构
  5. uniapp 消息推送与透传+语音播报
  6. 关于 Java 的线程状态
  7. (翻译)导航栏按钮的5类常见设计错误
  8. 微信强制加入群软件!易语言协议版,公开源码
  9. Qt绘制柱状图BarChart、饼状图PieChart、堆叠柱状图StackedChart、散点图ScatterChart
  10. 高光谱图像 空间分辨率