Windows进程崩溃问题定位方法

  Linux上进程崩溃通常会生成core文件,用gdb打开后执行bt命令即可查看堆栈。而在Windows平台上,我们通常会采用MiniDumpWriteDump来进行堆栈转储,而这需要对系统Api有一定的了解和编写一些代码。本文就结合实际项目经验,总结了一种无需编码即可记录进程崩溃堆栈的方法。

  原理简介:使用nstd工具进行进程崩溃时内存和堆栈转储。

  1. 编译Release版本时打开调试选项,将exe和pdb文件一起发布。

  2.使用批处理命令设置Windows系统在进程崩溃时调用的调试器为ntsd

@reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug" /v "Auto" /t REG_SZ /d "1" /f

该批处理指令,设置AeDebug调用前是否需要弹消息框确认?默认为0,设置1表示自动处理不弹确认框。如果大家安装过Visual Studio,可能都遇到过下列弹框:

这就是VS设置了AeDebug调试器后,遇到进程崩溃,然后弹框确认是否要附加到该进程进行调试的过程。

然后设置ntsd的调试转储指令:

@reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug" /v "Debugger" /t REG_SZ /d "D:\Dump\ntsd.exe -p %%ld -e %%ld -g -c \".dump /ma /u D:\Dump\dump.dmp; .logopen /t D:\Dump\dump.txt; .time; .echo Process Status:; ^|; .echo Thread Status:; ^~; .echo Stack Status:; kpn; .logclose; q\"" /f

我把的ntsd程序拷贝到d:\dump目录。

-p %%ld  传入进程ID,-c 执行dump指令:echo 打印线程信息,线程堆栈,最后再退出。

批处理安装脚本和ntsd程序我都已经打好包了,可以到这里下载

  3.下面通过一个实例来演示下效果:

#include <stdio.h>

void test2()
{
     int a = 1;
     int b = 0;
     int c = a/b;
}

void test1()
{
    test2();
}

int main(int argc, char** argv)
{
    test1();

    return 0;
}

我们通过除0错误来构造一次崩溃,test1和test2是为了演示调用堆栈。

通过本方法抓取的堆栈文本如下:

Opened log file ‘D:\Dump\dump_22d4_2014-09-30_15-15-33-062.txt‘
Debug session time: Tue Sep 30 15:15:33.063 2014 (GMT+8)
System Uptime: 2 days 3:35:54.545
Process Uptime: 0 days 0:00:00.923
  Kernel time: 0 days 0:00:00.015
  User time: 0 days 0:00:00.000
Process Status:
.  0	id: 3854	attach	name: D:\xcb\20140808\test\CoreDump\DumpExampleNormalStack.exe
Thread Status:
.  0  Id: 3854.3138 Suspend: 1 Teb: 7ffdf000 Unfrozen
Stack Status:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\ntdll.dll -
 # ChildEBP RetAddr
00 002dfb2c 01321038 DumpExampleNormalStack!test2(void)+0x18
01 002dfb34 01321048 DumpExampleNormalStack!test1(void)+0x8
02 002dfb3c 01321159 DumpExampleNormalStack!main(int argc = 1, char ** argv = 0x003ea488)+0x8
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll -
03 002dfb84 76e2ee1c DumpExampleNormalStack!__tmainCRTStartup(void)+0xfe
WARNING: Stack unwind information not available. Following frames may be wrong.
04 002dfb90 77ba37eb kernel32!BaseThreadInitThunk+0x12
05 002dfbd0 77ba37be ntdll!RtlInitializeExceptionChain+0xef
06 002dfbe8 00000000 ntdll!RtlInitializeExceptionChain+0xc2
Closing open log file D:\Dump\dump_22d4_2014-09-30_15-15-33-062.txt

切记:在Release版本中需要把调试选项打开,而且生成的pdb文件和exe要放在同一目录下。

如果是查找内存泄漏问题,可以参考本人另一篇博文。如果需要用谷歌查询技术问题,可以使用这里

时间: 2024-08-28 01:54:23

Windows进程崩溃问题定位方法的相关文章

windows进程间通讯的方法

版权声明 请尊重原创作品.转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正.   1.使用共享内存 代码如下: [cpp] view plaincopy void FileMapping(void) { //打开共享的文件对象. m_hMapFile = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("TestFileMap")); if (m_hMapFile) { //显

几种Windows进程通信

32位Windows采用虚拟内存技术使每个进程虚拟4G内存,在逻辑上实现了对进程之间数据代码的分离与保护.那么相应的进程之间的通信也就有必要整理掌握一下. Windows进程间通讯的方法有很多:管道.邮件槽.剪切板.共享内存.消息.套接字.RPC.DDE等. 但是他们大部分拥有一个共同的本质:利用Windows操作系统高2GB内核共享空间进行数据传递的桥梁,所以他们都是内核对象! 所以他们大部分都要遵循:A创建对象-->A写入数据-->B打开A创建的对象-->B读入数据的规则 下面着重通

C++技术问题总结-第15篇 内存泄露有哪些方法定位,崩溃有哪些方法定位

Visual C++内存泄露检测,可采用VLD工具. VLD:Visual Leak Detector.VLD是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号:可以得到泄露内存的完整数据:可以设置内存泄露报告的级别:并且是开源免费的. 官方网址:http://vld.codeplex.com/releases/view/82311 使用步骤: 1)官网下载VLD工具包. 2)解压后得到vld.h, vlda

windows客户端崩溃分析和调试

本文介绍windows上崩溃分析的一些手段,顺便提多进程调试.死锁等. 1.崩溃分析过程 1.1 确认错误码 无论是用windbg还是用vs,首先应该注意的是错误码,而90%以上的崩溃都是非法访问. 在非法访问时,可以看一下访问的目标地址.地址是0,或者离0很近(0x00000008或0xfffffffc), 一般和空指针相关.如果是一个貌似正常的地址,一般是对象已析构后访问其数据,或者堆破坏. 1.2确认崩溃对应的C++操作 什么是确认崩溃对应的C++操作: 比如非法访问,通常得有个mov指令

Windows下生成dump文件方法

[转载请注明出处]:http://blog.csdn.net/longlong530 一. 背景 没人能保证自己的软件在各种未知环境运行下,会木有任何问题.那么如果程序崩溃了怎么办?看日志?日志不全又怎么办?日志能帮你定位的多细致呢?如果能有种方法记录程序最后工作的状态,比如堆栈调用情况等,那么我们就可以获悉"它是如何挂掉的~" 二. 调研 我们对程序bug引起的程序崩溃的五种定位方法进行了调研,并最终选择方案5为我所在项目使用的程序崩溃定位方案. 方案1: 崩溃地址 + MAP文件

WINDOWS INSTALLER无法启动解决方法

WINDOWS INSTALLER无法启动解决方法 2011-04-13 10:18:32 标签:操作系统 windows 休闲 职场 第一步:使用记事本编写installer.reg文件,内容如下: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSIServer] “ImagePath”=- “ImagePath”=hex(2):25,00,53,00,79

如何使用fiddller跟踪windows进程发送的请求20140911

总结点:如何使用fiddller跟踪windows进程发送的请求 案例如下: 需求:运维工具提出需求,对每个插件的配置文件,同步到运维中心时先加密,然后传输到运维中心解密,存储到数据库 测试分析:这个需求不仅仅要保证客户端的配置文件和数据库中的一致,并且需要保证中途是经过加密的,因此我们的测试点需要注意两点: 1.配置文件传输时是经过加密的 2.在运维中心将加密的文件正确解密并存储在数据库中 以上第2点比较好校验和测试,关键是第一点如何确定文件传输时是经过加密的,为了获取传输数据,我们需要获取传

[python爬虫] Selenium常见元素定位方法和操作的学习介绍

这篇文章主要Selenium+Python自动测试或爬虫中的常见定位方法.鼠标操作.键盘操作介绍,希望该篇基础性文章对你有所帮助,如果有错误或不足之处,请海涵~ 前文目录: [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上) [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium [Python爬虫] Selenium自动访问Firefox和Chrome并实现搜索截图 [Python爬虫] Selenium实现自动登

Zabbix监控Windows进程重启

前段时间,一个朋友咨询我怎么监控Windows进程的重启.生产环境有监控进程的启动和关闭,但重启还没想过.经过一番思考和摸索后成功完成了监控,下面把监控思路和方法分享给大家. 我首先想到的是通过Zabbix自带的进程数监控(proc.num)来做,但有两个难点:一.进程数从1变为0再变为1,算是一次重启.触发器要判断三次连续的监控数据,不太好做:二.进程从关闭到下次启动,中间间隔多长时间算是一次重启呢? 然后想到了zabbix监控操作系统的重启,比如Windows系统重启的触发器:{Templa