Windows下 SetConsoleCtrlHandler函数怎么才能监听系统崩溃的情况

秀小川 2018-01-23 10:25:00


我的程序是一个控制台程序, 长期运行偶尔会出现崩溃的情况, 我想在崩溃是保存堆栈信息, 检查问题.

我用SetConsoleCtrlHandler可以监听到程序正常关闭时的消息, 当程序内部发生内存错误之类的,错误监听不到, 直接就关闭了, 有没有什么方法可以监听到程序崩溃的情况.
...全文
569 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 2018-01-27
  • 打赏
  • 举报
回复
引用 7 楼 秀小川的回复:
引用 6 楼 paschen 的回复:
引用 5 楼 K_Lord 的回复:
引用 4 楼 paschen 的回复:
[quote=引用 3 楼 K_Lord 的回复:][quote=引用 1 楼 paschen 的回复:]https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下
#include <Windows.h>bool CALLBACK exitHandler(DWORD evt){    CHAR FileName[MAX_PATH] = { 0 };    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si, sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));    GetModuleFileNameA(NULL, FileName, MAX_PATH);    g_server->CloseServer();    delete g_server;    if (!CreateProcessA(        FileName,        NULL,        NULL,        NULL,        FALSE,        0,        NULL,        NULL,        (LPSTARTUPINFOA)&si,        &pi))    {        printf("CreateProcess failed (%d).\n", GetLastError());        MessageBeep(MB_OK);    }    exit(1);}int main(){            SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);            SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);            int *ptr = nullptr;            *ptr = 3;  getchar();    return 0;}
我这个测试代码是想的出现错误程序自动重启。
这样呢:

#include <Windows.h>

LONG WINAPI exitUnhandledExceptionFilter(
	_In_ struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
	CHAR FileName[MAX_PATH] = { 0 };
	STARTUPINFO si;
	PROCESS_INFORMATION pi;


	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	GetModuleFileNameA(NULL, FileName, MAX_PATH);
	g_server->CloseServer();
	delete g_server;

	if (!CreateProcessA(
		FileName,
		NULL,
		NULL,
		NULL,
		FALSE,
		0,
		NULL,
		NULL,
		(LPSTARTUPINFOA)&si,
		&pi))
	{
		printf("CreateProcess failed (%d).\n", GetLastError());
		MessageBeep(MB_OK);
	}

	exit(1);
	return EXCEPTION_EXECUTE_HANDLER;
}


int main()
{
	SetUnhandledExceptionFilter(exitUnhandledExceptionFilter);
	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

	//SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);

	int *ptr = nullptr;
	*ptr = 3;

	getchar();
	return 0;
}
[/quote] 试了下这个方式, 在错误类型在main函数里面时, 可以有效果, 错误类型在别的被Main调用的方法里面就不行了, 还是直接退出. 我也尝试了在被调用函数的类构造函数里面写了SetUnhandledExceptionFilter(exitUnhandledExceptionFilter); 好像没有效果 [/quote] 应该不会,SetUnhandledExceptionFilter本身就是针对全局的,你再研究一下
秀小川 2018-01-27
  • 打赏
  • 举报
回复
引用 8 楼 paschen 的回复:
引用 7 楼 秀小川的回复:
引用 6 楼 paschen 的回复:
引用 5 楼 K_Lord 的回复:
[quote=引用 4 楼 paschen 的回复:][quote=引用 3 楼 K_Lord 的回复:][quote=引用 1 楼 paschen 的回复:]https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下
#include <Windows.h>bool CALLBACK exitHandler(DWORD evt){    CHAR FileName[MAX_PATH] = { 0 };    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si, sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));    GetModuleFileNameA(NULL, FileName, MAX_PATH);    g_server->CloseServer();    delete g_server;    if (!CreateProcessA(        FileName,        NULL,        NULL,        NULL,        FALSE,        0,        NULL,        NULL,        (LPSTARTUPINFOA)&si,        &pi))    {        printf("CreateProcess failed (%d).\n", GetLastError());        MessageBeep(MB_OK);    }    exit(1);}int main(){            SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);            SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);            int *ptr = nullptr;            *ptr = 3;  getchar();    return 0;}
我这个测试代码是想的出现错误程序自动重启。
这样呢:

#include <Windows.h>

LONG WINAPI exitUnhandledExceptionFilter(
	_In_ struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
	CHAR FileName[MAX_PATH] = { 0 };
	STARTUPINFO si;
	PROCESS_INFORMATION pi;


	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	GetModuleFileNameA(NULL, FileName, MAX_PATH);
	g_server->CloseServer();
	delete g_server;

	if (!CreateProcessA(
		FileName,
		NULL,
		NULL,
		NULL,
		FALSE,
		0,
		NULL,
		NULL,
		(LPSTARTUPINFOA)&si,
		&pi))
	{
		printf("CreateProcess failed (%d).\n", GetLastError());
		MessageBeep(MB_OK);
	}

	exit(1);
	return EXCEPTION_EXECUTE_HANDLER;
}


int main()
{
	SetUnhandledExceptionFilter(exitUnhandledExceptionFilter);
	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

	//SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);

	int *ptr = nullptr;
	*ptr = 3;

	getchar();
	return 0;
}
[/quote] 试了下这个方式, 在错误类型在main函数里面时, 可以有效果, 错误类型在别的被Main调用的方法里面就不行了, 还是直接退出. 我也尝试了在被调用函数的类构造函数里面写了SetUnhandledExceptionFilter(exitUnhandledExceptionFilter); 好像没有效果 [/quote] 应该不会,SetUnhandledExceptionFilter本身就是针对全局的,你再研究一下[/quote] 谢谢了, 我再试试!
秀小川 2018-01-26
  • 打赏
  • 举报
回复
引用 6 楼 paschen 的回复:
引用 5 楼 K_Lord 的回复:
引用 4 楼 paschen 的回复:
引用 3 楼 K_Lord 的回复:
[quote=引用 1 楼 paschen 的回复:]https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下
#include <Windows.h>bool CALLBACK exitHandler(DWORD evt){    CHAR FileName[MAX_PATH] = { 0 };    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si, sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));    GetModuleFileNameA(NULL, FileName, MAX_PATH);    g_server->CloseServer();    delete g_server;    if (!CreateProcessA(        FileName,        NULL,        NULL,        NULL,        FALSE,        0,        NULL,        NULL,        (LPSTARTUPINFOA)&si,        &pi))    {        printf("CreateProcess failed (%d).\n", GetLastError());        MessageBeep(MB_OK);    }    exit(1);}int main(){            SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);            SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);            int *ptr = nullptr;            *ptr = 3;  getchar();    return 0;}
我这个测试代码是想的出现错误程序自动重启。
这样呢:

#include <Windows.h>

LONG WINAPI exitUnhandledExceptionFilter(
	_In_ struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
	CHAR FileName[MAX_PATH] = { 0 };
	STARTUPINFO si;
	PROCESS_INFORMATION pi;


	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	GetModuleFileNameA(NULL, FileName, MAX_PATH);
	g_server->CloseServer();
	delete g_server;

	if (!CreateProcessA(
		FileName,
		NULL,
		NULL,
		NULL,
		FALSE,
		0,
		NULL,
		NULL,
		(LPSTARTUPINFOA)&si,
		&pi))
	{
		printf("CreateProcess failed (%d).\n", GetLastError());
		MessageBeep(MB_OK);
	}

	exit(1);
	return EXCEPTION_EXECUTE_HANDLER;
}


int main()
{
	SetUnhandledExceptionFilter(exitUnhandledExceptionFilter);
	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

	//SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);

	int *ptr = nullptr;
	*ptr = 3;

	getchar();
	return 0;
}
[/quote] 试了下这个方式, 在错误类型在main函数里面时, 可以有效果, 错误类型在别的被Main调用的方法里面就不行了, 还是直接退出. 我也尝试了在被调用函数的类构造函数里面写了SetUnhandledExceptionFilter(exitUnhandledExceptionFilter); 好像没有效果
paschen 2018-01-23
  • 打赏
  • 举报
回复
引用 3 楼 K_Lord 的回复:
引用 1 楼 paschen 的回复:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下
秀小川 2018-01-23
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
赵4老师 2018-01-23
  • 打赏
  • 举报
回复
http://blog.csdn.net/zhao4zhong1/article/details/53078924 老司机找bug的十年心路历程
paschen 2018-01-23
  • 打赏
  • 举报
回复
引用 5 楼 K_Lord 的回复:
引用 4 楼 paschen 的回复:
引用 3 楼 K_Lord 的回复:
引用 1 楼 paschen 的回复:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下
#include <Windows.h>bool CALLBACK exitHandler(DWORD evt){    CHAR FileName[MAX_PATH] = { 0 };    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si, sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));    GetModuleFileNameA(NULL, FileName, MAX_PATH);    g_server->CloseServer();    delete g_server;    if (!CreateProcessA(        FileName,        NULL,        NULL,        NULL,        FALSE,        0,        NULL,        NULL,        (LPSTARTUPINFOA)&si,        &pi))    {        printf("CreateProcess failed (%d).\n", GetLastError());        MessageBeep(MB_OK);    }    exit(1);}int main(){            SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);            SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);            int *ptr = nullptr;            *ptr = 3;  getchar();    return 0;}
我这个测试代码是想的出现错误程序自动重启。


这样呢:


#include <Windows.h>

LONG WINAPI exitUnhandledExceptionFilter(
_In_ struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
CHAR FileName[MAX_PATH] = { 0 };
STARTUPINFO si;
PROCESS_INFORMATION pi;


ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

GetModuleFileNameA(NULL, FileName, MAX_PATH);
g_server->CloseServer();
delete g_server;

if (!CreateProcessA(
FileName,
NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
(LPSTARTUPINFOA)&si,
&pi))
{
printf("CreateProcess failed (%d).\n", GetLastError());
MessageBeep(MB_OK);
}

exit(1);
return EXCEPTION_EXECUTE_HANDLER;
}


int main()
{
SetUnhandledExceptionFilter(exitUnhandledExceptionFilter);
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

//SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);

int *ptr = nullptr;
*ptr = 3;

getchar();
return 0;
}
秀小川 2018-01-23
  • 打赏
  • 举报
回复
引用 4 楼 paschen 的回复:
引用 3 楼 K_Lord 的回复:
引用 1 楼 paschen 的回复:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
我看过这个, 按照这个文档,好像是只能监听一部分系统事件, 但是对于程序奔溃的情况检测不到。 有没有别的方法?
有没一个示例代码,我帮你研究下

#include <Windows.h>

bool CALLBACK exitHandler(DWORD evt)
{
    CHAR FileName[MAX_PATH] = { 0 };
    STARTUPINFO si;
    PROCESS_INFORMATION pi;


    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    GetModuleFileNameA(NULL, FileName, MAX_PATH);
    g_server->CloseServer();
    delete g_server;

    if (!CreateProcessA(
        FileName,
        NULL,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        (LPSTARTUPINFOA)&si,
        &pi))
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        MessageBeep(MB_OK);
    }
    exit(1);
}


int main()
{

            SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

            SetConsoleCtrlHandler((PHANDLER_ROUTINE)exitHandler, true);

            int *ptr = nullptr;
            *ptr = 3;

  getchar();
    return 0;
}


我这个测试代码是想的出现错误程序自动重启。

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧