[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: how can I get a backtrace from inside my program?



jcupitt gmail com wrote:
> 2008/10/31 Brian J. Tarricone <bjt23 cornell edu>:
>> Garth's KidStuff wrote:
>>> I have a large Gtk app running on Ubuntu and I'd love to be able to log
>>> stack trace information when unusual events occur.  Any ideas on where to
>>> look for this?
>> If you don't mind that it only works on Linux, with glibc and gcc, take a
>> look at backtrace() and backtrace_symbols() (or backtrace_symbols_fd()).
>>  I've never used it myself, but that might be what you're looking for.
> 
> Another option (brace yourself, this is very hacky) is to start gdb,
> attach to yourself, send a "bt" (backtrace) command, and capture the
> output. It's slow, but it does work, sort of, and it would be slightly
> more portable.

gdb also ships a binary called gstack that does the same.  Something like this
will send the stacktrace to stderr:

static void
stack_trace (void)
{
  int pid = getpid ();
  int child_pid = fork ();

  if (child_pid) {
    waitpid (child_pid, NULL, 0);
  } else {
      char pid[10];
      snprintf (pid, sizeof (pid), "%d", pid);
      close (1);
      dup2 (2, 1);
      execlp ("gstack", "gstack", pid, NULL);
      g_error ("running gstack failed.");
  }
}

behdad



> Of course your app will need to be built with -g, the user will need
> to have gdb installed, and the ugly way I've done it in this scrap of
> code is horribly insecure. You'd need to trim the output down a bit
> too.
> 
> -----------
> #include <sys/types.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <string.h>
> 
> /* Largest output we can capture.
> */
> #define MAX_TRACE (1024)
> 
> char *
> getstacktrace( const char *argv0 )
> {
>       pid_t pid = getpid();
>       char output[MAX_TRACE];
>       char cmd[256];
>       FILE *fp;
>       int i;
>       int ch;
> 
>       snprintf( cmd, 256,
>               "echo bt > /tmp/poop | gdb -batch %s %d -x /tmp/poop",
>               argv0, pid );
>       if( !(fp = popen( cmd, "r" )) )
>               return( NULL );
> 
>       for( i = 0; i < MAX_TRACE - 1 && (ch = fgetc( fp )) != EOF; i++ )
>               output[i] = ch;
>       output[i] = 0;
> 
>       pclose( fp );
> 
>       return( strdup( output ) );
> }
> 
> int
> main( int argc, char **argv )
> {
>       char *trace;
> 
>       if( (trace = getstacktrace( argv[0] )) ) {
>               printf( "stack trace:\n%s", trace );
>               free( trace );
>       }
> 
>       return( 0 );
> }
> --------------
> 
> J
> _______________________________________________
> gtk-app-devel-list mailing list
> gtk-app-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
> 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]