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]