Linux是否会记录守护进程抛出的未捕获异常?

3

我用C++编写了一个Linux守护进程。代码大致如下:

int main(int argc, char** argv)
{
    daemon(1, 0); // Daemonize itself, retaining the current working directory and redirecting stdin, stdout and stderr to /dev/null.
    // My program logic goes here
}

问题是,我的程序逻辑偶尔会抛出异常。我该如何捕获这些异常,以便我知道哪里出了问题?
我知道对于一个普通的控制台应用程序,未捕获的异常将被转储到控制台。在我的情况下,在调用daemon(1,0)之后,控制台不再可访问。
在Windows上,任何未捕获的异常都将被操作系统保存,并可以通过计算机管理中的事件查看器查看。Linux上是否有类似的机制?

显然,您可以将代码放在try/catch块中,然后在catch块中以任何您想要的方式记录它。但是,您的问题似乎是在询问当一个被守护进程以未捕获的异常终止时会发生什么。 - Andrew Tomazos
对我来说,显而易见的解决方案是打开一个用于日志记录的文件,而不是重定向到/dev/null,并在守护进程停止后检查该文件。 - Matthieu M.
我对你用“普通控制台应用程序”作比喻感到困惑。当异常未被捕获时,普通控制台应用程序是死的。你是否也指的是守护进程死亡的情况? - Kerrek SB
2个回答

5
你有两个解决方案:
  • one: you change your call to the daemon function to

    daemon(1,1);
    

    which will let the program still have access to stdout and subsequently the default behaviour of dumping uncaught exceptions to the console will be preserved.

  • two: you don't change the call, but you add a global try { /* main code here */ } catch(...){ /* logging code here */ } to log any uncaught exception to file.


切换到守护进程(1,1)是最简单的方法。谢谢。 - Jacky Lee
第二个选项很有帮助。 - Vitaly Isaev

4
假设你已经按照didierc的建议解决了日志记录问题,你可以考虑安装std::set_terminate()处理程序,这样你就可以看到未处理异常的堆栈跟踪
#include <iostream>
#include <stdexcept>

#include <execinfo.h>

void
handler()
{
    void *trace_elems[20];
    int trace_elem_count(backtrace( trace_elems, 20 ));
    char **stack_syms(backtrace_symbols( trace_elems, trace_elem_count ));
    for ( int i = 0 ; i < trace_elem_count ; ++i )
    {
        std::cout << stack_syms[i] << "\n";
    }
    free( stack_syms );

    exit(1);
}   

int foo()
{
    throw std::runtime_error( );
}

int
main()
{
    std::set_terminate( handler );
    foo();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接