我有以下问题:我有一个用 C++ 编写的应用程序(永远不会结束的服务器)作为服务运行,其中包含主线程内部还有 3 个线程(主要执行 IO)。
在主循环中,我捕获了所有可能的异常。
该进程终止,主循环或线程本身没有打印任何内容。我在事件日志中看到该进程以代码 1000 停止。
- Windows 是否像在 unix 中一样创建核心文件?
- 如果从事件日志中我得到一个内存地址,有没有办法知道它发生在应用程序的哪个部分?
- 也许这是一个线索:在它发生的同时,我启动了另一个应用程序(不是同一类型)。
我有以下问题:我有一个用 C++ 编写的应用程序(永远不会结束的服务器)作为服务运行,其中包含主线程内部还有 3 个线程(主要执行 IO)。
在主循环中,我捕获了所有可能的异常。
该进程终止,主循环或线程本身没有打印任何内容。我在事件日志中看到该进程以代码 1000 停止。
尝试将 windbg 设置为事后调试器。
windbg -I
”从 windbg 使用"kb" or "!uniqstack"
查看堆栈跟踪。
在这里查看更多命令。
并在这里查看如何分析。
并尝试使用 SEH:
#include "windows.h"
#include "stdio.h"
DWORD FilterFunction()
{
printf("you will see this message first.\n");
return EXCEPTION_EXECUTE_HANDLER;
}
int main(char** argv, int c)
{
__try
{
int this_will_be_zero = (c == 9999);
int blowup = 1 / this_will_be_zero;
}
__except ( FilterFunction())
{
printf("you will see this message\n");
}
return 0;
}
在构建应用程序时需要使用 /EHa 编译器开关,以便使用 C++ try/catch 构造捕获 Windows 结构化异常(例如访问冲突)。
在 Visual Studio 中,这是在项目属性配置属性 -> C/C++ -> 代码生成 -> 启用 C++ 异常中。你想要“是的,有 SEH 异常 (/EHa)”。我记得阅读设置它有一些明显的缺点,尽管我不记得它们到底是什么。
编辑:正如whunmr所建议的,直接使用结构化异常可能比 /EHa 更好
请记住catch(...)
,除非您使用结构化异常处理,否则不会拦截代码中可能出错的所有内容。例如
#include “stdio.h” int main(char** argv, int c) { 尝试 { int this_will_be_zero = (c == 9999); int 爆破 = 1 / this_will_be_zero; } 抓住 (...) { printf("你不会看到这条信息\n"); } }
Windows 是否像在 unix 中一样创建核心文件?
它不会,自动。但是,您可以通过在代码中实现它或使用外部应用程序如 windbg 或Dr. Watson来启用此类文件
如果从事件日志中我得到一个内存地址,有没有办法知道它发生在应用程序的哪个部分?
一般来说,如果您不保留调试信息文件(pdb),则没有办法
也许这是一个线索:在它发生的同时,我启动了另一个应用程序(不是同一类型)。
这不是有用的信息,除非两个应用程序相互交互
Windows 将根据以下设置将您使用的任何程序用作调试器:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug] “自动”=“0” "调试器"="My_Debugger" -p %ld -e %ld" "UserDebuggerHotKey"=dword:00000000
您可以更改My_Debugger
为用于调试的任何程序/IDE 的完整路径。
这通常设置为 Dr Watson,它将创建一个不是您想要的崩溃日志条目。