我有以下问题:我有一个用C ++编写的应用程序(永远不会结束的服务器)作为服务运行,包含主线程内部还有3个线程(主要是做IO)。
在主循环中,我捕获所有可能的异常。
进程终止,主循环或线程本身都没有打印任何内容。我在事件日志中看到进程因代码1000而停止。
答案 0 :(得分:5)
尝试将windbg设置为事后调试器。
windbg -I
”使用"kb" or "!uniqstack"
来查看堆栈跟踪。
look here for more commands.
并查看here了解如何进行分析。
并尝试使用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;
}
答案 1 :(得分:2)
请记住,除非您使用结构化异常处理,否则catch(...)
不会拦截代码中可能出错的所有内容。例如
#include "stdio.h" int main(char** argv, int c) { try { int this_will_be_zero = (c == 9999); int blowup = 1 / this_will_be_zero; } catch (...) { printf("you won't see this message\n"); } }
答案 2 :(得分:2)
在构建应用程序时需要使用/ EHa编译器开关,以便使用C ++ try / catch构造捕获窗口结构化异常(例如访问冲突)。
在Visual Studio中,这是项目属性Configuration Properties - > C / C ++ - >代码生成 - >启用C ++例外。你想要“是的SEH异常(/ EHa)”。我记得阅读设置这有一些明显的缺点,虽然我不记得它们到底是什么。
链接:MSDN on C++ exception handling model
编辑:正如 whunmr 所示,直接使用结构化异常可能比/ EHa更好主意
答案 3 :(得分:1)
Windows是否像在unix中一样创建Core文件?
它没有,自动。但是你可以通过启用这样的文件 要么在代码中实现,要么使用外部应用程序 作为windbg,或Dr. Watson
如果从事件日志中得到一个内存地址,有没有办法知道应用程序中的哪个部分发生了?
如果不保留调试信息文件(pdb)
,一般情况下是没有办法的也许这是一个线索:在它发生的同时我开始了另一个应用程序(不是同一类型)。
这不是有用的信息,除非两个应用程序相互交互
答案 4 :(得分:1)
Windows将根据以下设置使用您用作调试器的任何程序:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug] "Auto"="0" "Debugger"="My_Debugger" -p %ld -e %ld" "UserDebuggerHotKey"=dword:00000000
您可以将My_Debugger
更改为用于调试的任何程序/ IDE的完整路径。
这经常被设置为Dr Watson,它将创建崩溃的日志条目,这不是你想要的。