windows系统下的异常处理是try,except,linux下可以用信号来模拟捕捉异常,其实我感觉还是windows下的比较好用。

分两步,设置信号处理函数,设置一个还原点。

设置信号处理函数

一般崩溃时都是收到这两个信号。

::signal(SIGSEGV, KFXDoSigSEGV);
::signal(SIGFPE, KFXDoSigSEGV);

设置还原点,一般都是在主循环上面设置

sigjmp_buf context;//全局对象
.... 
sigsetjmp(gDoSEGV.context,1);//主循环上方

while(1)
{
    main_loop();
}

发生异常时

会调用我们设置的信号处理函数,然后会执行siglongjmp,跳转到我们设置的还原点,重新进入主循环。

static void KFXDoSigSEGV(int nSig)
{
    // 打印一些崩溃信息
    siglongjmp(context, 1);
}

思考

不能完全依赖这种方法避免服务器崩溃, 不然会掩盖错误。现在的做法时捕捉到崩溃的时候,打印调用堆栈,然后通知研发计数+1,如果连续捕获到1000次崩溃,就走默认处理真正崩溃,每次捕获后立刻通知研发人员查代码。

如果是低概率的崩溃事件,可以不影响游戏的其他玩家。

如果是极高概率出现,1000次以后也会真正的崩溃。