views:

112

answers:

2

Now I'm using function like this:

void print_trace() {
    char pid_buf[30];
    sprintf(pid_buf, "%d", getpid());
    char name_buf[512];
    name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
    int child_pid = fork();
    if (!child_pid) {           
        execlp("gdb", "gdb", "-batch", "-n", "-ex", "set pagination off", "-ex", "thread apply all bt full", name_buf, pid_buf, NULL);
        abort(); /* If gdb failed to start */
    } else {
        wait(child_pid);
    }
}              

And I see details of print_trace in the output. Also I can't turn off pagination because I can execute only 1 command.

How this function can be improved?

A: 

Isn't abort() simpler?

That way if it happens in the field the customer can send you the core file (I don't know many users who are involved enough in my application to want me to force them to debug it).

Motti
I don't need to abort. I need a stack trace. Program can continue after printing it. And I like the verbosity of "bt full"
Vi
Also print_trace() way is rather unintrusive. If `gdb` in not found the program can just continue without printing a stacktrace.
Vi
@Vi, OK sorry I wasn't any help :o/
Motti
A: 

If you're using Linux, the standard C library includes a function called backtrace, which populates an array with frames' return addresses, and another function called backtrace_symbols, which will take the addresses from backtrace and look up the corresponding function names. These are documented in the GNU C Library manual.

Those won't show argument values, source lines, and the like, and they only apply to the calling thread. However, they should be a lot faster (and perhaps less flaky) than running GDB that way, so they have their place.

Jim Blandy
Actually snippet that I insert into program firstly outputs backtrace with backtrace_symbols and then starts gdb to output fully annotated stack traces for all threads. If gdb fails, I still has the `backtrace`'s stacktrace.
Vi