3

I have written a Linux daemon in C++. The code is something like this:

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
}

The problem is, my program logic throws exceptions occasionally. How do I catch the exceptions so that I can know where goes wrong?

I know that for a plain console application, the uncaught exception will be dumped to the console. In my case, after calling daemon(1, 0), the console is no longer accessible.

On Windows, any uncaught exceptions will be saved by the OS, and can be viewed via the Event Viewer in Computer Management. Is there a similar mechanism on Linux?

Jacky Lee
  • 1,193
  • 3
  • 13
  • 22
  • Clearly you can put your code in a try/catch block and then log it however you want in the catch block. Your question however seems to be asking what happens when a demonized process terminates with an uncaught exception. – Andrew Tomazos Nov 04 '12 at 14:02
  • The obvious solution to me seems to open a file for logging instead of redirecting to `/dev/null` and check the file once the daemon stops. – Matthieu M. Nov 04 '12 at 14:04
  • I'm confused by your analogy with the "plain console application". A plain console application is *dead* when an exception remains uncaught. Are you also referring to situations where your daemon dies? – Kerrek SB Nov 04 '12 at 14:12

2 Answers2

5

You have two solutions:

  • 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.

didierc
  • 14,572
  • 3
  • 32
  • 52
4

Assuming you figure out your logging as didierc suggests, You might consider installing a std::set_terminate() handler so you can see the stack trace from the unhandled exception

#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();
}
Community
  • 1
  • 1
Sam Miller
  • 23,808
  • 4
  • 67
  • 87