Windows应用崩溃捕获

Windows应用崩溃捕获

一、序言

​ 最近发现我们自己的程序会因为各种各样的原因异常崩溃,但却没有日志记录,也没有任何弹窗提示,电脑设置了定时重启,重启自动运行后程序就可以正常运行了,但这之间崩溃的原因没有办法获取,很是苦恼。因此要想办法对其进行监控。

​ 最开始我的想法是这样的:写一个脚本,每隔2s进行一次截屏,再查找进程,如果发现进程已经消失,则保存截屏图片,再写日志记录崩溃时间,这样就可以在之后看到程序崩溃前 1~2 秒的状态。BUT,我们的程序直接在主机运行,没有显示器,需要虚拟一个显示器,这样一来,对系统资源的消耗就太大了。对于扣扣索索的我,这显然不是好的解决办法。况且,这样做根本是治标不治本,即便获得了截图,也没有什么参考价值,毕竟程序自动运行,崩溃肯定是由于内部问题(例如内存溢出呀,当然只是举例,不可能犯这么低级的错误)造成。经过我不懈的查找,终于发现了一名大佬分享的文章,经过努力实现了我的目的,特此记录。

参考大佬地址 https://developer.aliyun.com/article/229733

二、实现

我们使用windows自带的崩溃捕获dump的功能,只需要我们手动设置一下即可使用。

1.启动 Windows Error Reporting Service 服务。

在这里插入图片描述
在这里插入图片描述

2.移除默认的调试器。

打开注册表编辑器(win+r 输入 regedit

如果你的机器装了VS开发工具,会在注册表里写入调试器地址,需要把它删除

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger

在 64 位 操作系统上也删除以下注册表项:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger

3.执行下面注册表脚本,添加程序崩溃捕获dump(这个设置是捕获所有的程序崩溃的dump,可能会产生的文件比较多也比较大)

将下面的内容复制粘贴到 txt 中(注意第4行的 C:\CrashDump 是你dump文件的保存路径,可根据需要进行更改

@echo off  
echo 正在启用Dump...  
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"  
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDump" /f  
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f  
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f  
echo Dump已经启用  
pause  
@echo on

点击 file,选择另存为,保存类型选择所有文件,文件名后缀为 bat,编码选择 ANSI。
在这里插入图片描述
以管理员身份运行生成的 .bat 文件,得到如下结果,表明设置完成。
在这里插入图片描述

4.测试结果

编写C++程序:

#include<iostream>

using namespace std;

int mian()
{
    int i = 1/0; //此处用1除以0造成程序崩溃
    return 0;
}

编译生成 test.exe,运行,观察 C:\CrashDump文件下是否生成对应的 .dmp 文件。

在这里插入图片描述

表明我们配置成功。

三、分析dump文件。

要分析 dump 文件需要使用 windbg 这个工具,可从腾讯软件中心下载。

下载后的安装均为默认,此处省略。

安装完成后,我们点击开始在所有应用中找到它

在这里插入图片描述

打开后点击 Ctrl+D,选择我们刚才生成的文档。

可以看到如下结果

在这里插入图片描述

至此,我们就可以利用 windows 自带的异常捕获捕获到应用的崩溃原因,简直不要太爽。

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
在您的日常开发工作当中,是否曾碰到过以下困扰: (1)当您的应用程序在实际环境下运行时,由于没有VC++调试环境而无法看到TRACE输出的调试信息。 (2)当您的应用程序在实际环境下运行时,突然出现程序异常导致应用程序崩溃时,无法定位问题出在哪里。 本工具软件是一个用于在Release后运行于真实环境下的应用软件的调试工具(当然也可以调试Debug版本)而无需VC++环境,它可以捕获应用软件的TRACE输出信息进行跟踪显示,同时还能对应用软件在运行时出现的异常崩溃进行源码级的定位,非常方便程序员快速定位并解决应用软件开发中的深度BUG。 * 对于DEBUG版本的应用程序,可脱离VC++开发环境直接捕获程序中"TRACE"输出的调试信息。 * 对于RELEASE版本的应用程序,只要加入以下代码就可以脱离VC++开发环境直接捕获程序中_TRACE输出的调试信息。 --------------------------------------------------- #ifndef _DEBUG void _TRACE( LPCTSTR pszFormat, ... ) { char buf[512]; va_list argList; va_start(argList, pszFormat ); vsprintf( buf, pszFormat, argList ); va_end(argList); OutputDebugString( buf ); } #endif --------------------------------------------------- * Tracer能够同时支持多个应用程序的调试信息输出,每个应用程序的输出独占一个窗口,特别适合C-S应用的并行调试。 * Tracer可以对应用程序的调试输出信息进行过滤,使您专注于特定模块或特定功能的运行跟踪。 * Tracer可以保存应用程序的调试输出信息到文件中,以便后续的问题诊断分析。 * Tracer还有一个强大的错误定位功能,当Release版本的应用程序在实际环境下运行出现异常而崩溃时,Tracer可以大显身手为您快速准确定位问题所在。只要您记录下应用程序发生崩溃时的地址信息(一般都会在Windows弹出的崩溃信息窗口中显示)并提供给Tracer一个该应用程序的map文件,Tracer将会为您计算出该应用程序崩溃发生于源程序的哪个模块文件、哪个函数以及具体源代码行。 * 发布的软件包中附带有一个带源码的Demo程序,演示了如何使用_TRACE将调试信息输出到Tracer的窗口中,同时演示了当Demo程序运行崩溃时通过Tracer进行BUG的源码定位,您可以马上看到Tracer所报告出来的错误所在的源代码行与您自己在源码中所发现的BUG是否一致。 * 如果您在使用Tracer软件的过程中遇到问题需要帮助,请email到:hynoo.tech@gmail.com,我们会及时为您解答。
### 回答1: 要在 Windows 内核中获取应用程序的用户模式堆栈,可以使用以下方法: 1. 获取进程句柄 使用函数 PsGetCurrentProcess() 获取当前进程句柄。 2. 获取进程对象 使用函数 ObReferenceObjectByHandle() 获取进程对象。 3. 获取线程列表 使用函数 PsGetNextProcessThread() 获取进程对象的线程列表。 4. 获取线程堆栈 使用函数 KeStackAttachProcess() 将当前线程切换到目标进程的上下文中,然后使用函数 KeGetCurrentThreadStackLimit() 获取当前线程的堆栈限制地址,再使用函数 KeGetCurrentThreadStackBase() 获取当前线程的堆栈基地址。 5. 计算堆栈大小 通过堆栈基地址和堆栈限制地址计算出堆栈大小。 6. 获取堆栈内容 使用函数 RtlCopyMemory() 将堆栈内容复制到缓冲区中。 完整的代码示例: ```cpp PEPROCESS Process; HANDLE ProcessHandle; NTSTATUS Status; KAPC_STATE ApcState; PKTHREAD Thread; ULONG StackSize; ULONG_PTR StackBase; ULONG_PTR StackLimit; PCHAR StackBuffer; // 获取当前进程句柄 Process = PsGetCurrentProcess(); Status = ObOpenObjectByPointer(Process, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ProcessHandle); if (!NT_SUCCESS(Status)) { return Status; } // 获取进程对象 if (ProcessHandle) { // 遍历线程列表 for (Thread = PsGetNextProcessThread(Process, NULL); Thread != NULL; Thread = PsGetNextProcessThread(Process, Thread)) { // 切换到目标进程上下文 KeStackAttachProcess(&Thread->tcb, Process); // 获取堆栈信息 StackLimit = (ULONG_PTR)KeGetCurrentThreadStackLimit(); StackBase = (ULONG_PTR)KeGetCurrentThreadStackBase(); StackSize = (ULONG)(StackBase - StackLimit); // 分配缓冲区 StackBuffer = (PCHAR)ExAllocatePoolWithTag(NonPagedPool, StackSize, 'stak'); if (StackBuffer) { // 复制堆栈内容 RtlCopyMemory(StackBuffer, (PVOID)StackLimit, StackSize); // 处理堆栈内容 // ... // 释放缓冲区 ExFreePoolWithTag(StackBuffer, 'stak'); } // 恢复当前线程上下文 KeUnstackDetachProcess(&ApcState); } // 关闭进程句柄 ZwClose(ProcessHandle); } return STATUS_SUCCESS; ``` ### 回答2: Windows 内核中有一种功能称为内存转储(Memory Dump),它可以存储系统在发生错误或崩溃时的内存状态。内存转储可以包含应用程序、操作系统和设备驱动程序的数据,可以为调试和故障排除提供重要信息。 在Windows操作系统中,应用层堆栈(Application Layer Stack)是指在系统崩溃时被保存的应用程序的运行状态信息。应用层堆栈包含了应用程序的调用栈(Call Stack),记录了程序执行过程中的函数调用关系。 当系统发生错误或崩溃时,Windows内核会生成一个内核转储文件,也称为内核转储(Kernel Dump)。这个内核转储文件包含了整个系统的内存状态,可以通过分析它来识别问题的根本原因。在这个内核转储文件中,应用层堆栈是其中的一部分。 应用层堆栈中的信息可以用来确定哪个应用程序最后导致系统崩溃或故障。分析应用层堆栈可以帮助开发人员或系统管理员快速定位问题,并进行相应的修复。例如,可以查看堆栈中的函数调用关系,检查是否有无线循环、内存泄露或访问越界等问题。 要获取Windows内核转储文件中的应用层堆栈信息,可以使用一些调试工具,例如WinDbg。这些工具可以加载内核转储文件,并提供一个交互式的调试环境,用于分析应用层堆栈和其他相关信息。 总之,通过分析Windows内核转储文件中的应用层堆栈,可以了解系统崩溃的原因,并采取相应的措施来修复问题。这是一项重要的技术,可以帮助保证Windows系统的稳定性和可靠性。 ### 回答3: 在Windows内核中,应用层堆栈是指一个线程在执行过程中所使用的函数调用栈。当应用程序崩溃或发生异常时,Windows内核会产生一个称为dump文件的二进制文件,用于记录当前的内存状态和调用堆栈信息。 Windows内核dump应用层堆栈的过程如下: 首先,当应用程序发生崩溃或异常时,操作系统会拦截这个事件,并捕获相关的异常信息。然后,操作系统会保存这些信息和应用层堆栈的调用信息到一个特定的内存区域中。 接下来,操作系统会创建一个dump文件,将之前保存的内存信息和堆栈调用信息写入其中。这个dump文件通常是一个二进制文件,可以使用调试工具来进行分析和调试。 最后,开发人员或系统管理员可以使用不同的调试工具来分析dump文件,以找出导致应用程序崩溃或异常的原因。通过分析应用层堆栈的调用信息,可以确定问题发生的具体位置和可能的原因,从而进行修复或优化。 总之,Windows内核dump应用层堆栈是一种记录应用程序崩溃或异常信息的机制,它可以为开发人员或系统管理员提供快速的故障诊断和问题解决的手段。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐先生没洗头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值