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上有类似的机制吗?

4

2 回答 2

5

你有两个解决方案:

  • 一:您将对守护程序函数的调用更改为

    daemon(1,1);
    

    这将使程序仍然可以访问标准输出,随后将保留将未捕获的异常转储到控制台的默认行为。

  • 二:您不更改调用,但添加一个全局try { /* main code here */ } catch(...){ /* logging code here */ }以将任何未捕获的异常记录到文件中。

于 2012-11-04T14:03:02.800 回答
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();
}
于 2012-11-04T14:14:50.413 回答