C++ WonderTrader源码分析之异常捕获

一、介绍

在工程TestDtPorterv中调用的getRunner().start(bAsync) 有使用到程序的异常捕获处理

void install_signal_hooks(TracerLogCallback cbLog, ExitHandler sigHandler = NULL)
{
	g_cbSignalLog = cbLog;
	g_exitHandler = sigHandler;
	for (int s = 1; s < NSIG; s++)
	{
		signal(s, handle_signal);
	}
}

install_signal_hooks([this](const char* message) {
	if(!_to_exit)
		WTSLogger::error(message);
}, [this](bool toExit) {
	if (_to_exit)
		return;
	_to_exit = toExit;
	WTSLogger::info("Exit flag is {}", _to_exit);
});

二、信号安装机制

void install_signal_hooks(TracerLogCallback cbLog, ExitHandler sigHandler) {
    g_cbSignalLog = cbLog;      // 设置日志回调
    g_exitHandler = sigHandler; // 设置退出回调
    
    // ⭐关键:为所有信号安装统一处理函数⭐
    for (int s = 1; s < NSIG; s++) {
        signal(s, handle_signal);
    }
}

三、信号处理系统

而信号的捕获处理主要在文件SignalHook.h中,该文件主要为跨平台的信号处理系统,用于捕获和处理程序运行时的各种系统信号

1. Windows平台信号处理
用户中断信号
case SIGINT:          // Ctrl+C 中断
case SIGBREAK:        // Ctrl+Break 序列
    g_cbSignalLog("app interrupted");
    if (g_exitHandler)
        g_exitHandler(signum);  // 优雅退出
    else
        exit(signum);           // 直接退出
    break;
严重错误信号(需要调用栈)
case SIGILL:          // 非法指令
case SIGFPE:          // 浮点异常
case SIGSEGV:         // 段错误
case SIGABRT:         // 异常终止
    sprintf(buf, "app stopped by signal %d", signum);
    g_cbSignalLog(buf);
    print_stack_trace(g_cbSignalLog);  // ⭐打印调用栈⭐
    // 然后退出...
2. Linux/Unix平台信号处理
可忽略的信号
case SIGURG:       // socket紧急条件
case SIGCONT:      // 继续执行
case SIGCHLD:      // 子进程状态改变
case SIGIO:        // I/O可用
case SIGWINCH:     // 窗口大小改变
    sprintf(buf, "app discard signal %d", signum);
    g_cbSignalLog(buf);
    break;  // ⭐只记录,不退出⭐
进程控制信号
case SIGSTOP:      // 停止进程(无法捕获)
case SIGTSTP:      // 键盘停止信号(Ctrl+Z)
case SIGTTIN:      // 后台读终端
case SIGTTOU:      // 后台写终端
    sprintf(buf, "app stopped by signal %d", signum);
    g_cbSignalLog(buf);
    // 执行退出处理...
严重错误信号(生成core dump)
case SIGQUIT:      // 退出程序
case SIGILL:       // 非法指令
case SIGTRAP:      // 跟踪陷阱
case SIGABRT:      // 异常终止
case SIGFPE:       // 浮点异常
case SIGBUS:       // 总线错误
case SIGSEGV:      // 段错误
    g_cbSignalLog("segmentation violation");
    print_stack_trace(g_cbSignalLog);  // ⭐打印调用栈⭐
    // 退出处理...

四、堆栈打印系统

堆栈处理主要在文件StackWalker.h中,StackWalker是一个用于遍历程序调用栈的工具类,它能够:

  • 获取当前线程的函数调用链
  • 解析函数名、文件名、行号等调试信息
  • 将调用栈信息格式化输出

比如在程序崩溃时会打印具体的崩溃信息

install_signal_hooks([](const char* message) {
	std::cout << message << std::endl;
	}, [](bool toExit) {
		std::cout << "Exit flag is {}" << toExit << std::endl;
		});
	while (1) {
		Sleep(2000);
		char* p = nullptr;
		std::cout << *p << std::endl;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值