Main Page | Class List | Directories | File List | Class Members | File Members

gerror.c File Reference

#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "glib.h"
#include <sys/types.h>
#include <time.h>

Go to the source code of this file.

Defines

#define SELECT_MASK   fd_set

Functions

static void stack_trace (char **args)
void g_on_error_query (const gchar *prg_name)
void g_on_error_stack_trace (const gchar *prg_name)
static void stack_trace_sigchld (int signum)

Variables

volatile gboolean glib_on_error_halt = TRUE
static gboolean stack_trace_done = FALSE


Define Documentation

#define SELECT_MASK   fd_set
 

Definition at line 67 of file gerror.c.

Referenced by g_poll(), and stack_trace().


Function Documentation

void g_on_error_query const gchar prg_name  ) 
 

Definition at line 86 of file gerror.c.

References g_get_prgname(), g_on_error_stack_trace(), glib_on_error_halt, and TRUE.

Referenced by main().

00087 {
00088   static const gchar *query1 = "[E]xit, [H]alt";
00089   static const gchar *query2 = ", show [S]tack trace";
00090   static const gchar *query3 = " or [P]roceed";
00091   gchar buf[16];
00092 
00093   if (!prg_name)
00094     prg_name = g_get_prgname ();
00095   
00096  retry:
00097   
00098   if (prg_name)
00099     fprintf (stdout,
00100              "%s (pid:%u): %s%s%s: ",
00101              prg_name,
00102              (guint) getpid (),
00103              query1,
00104              query2,
00105              query3);
00106   else
00107     fprintf (stdout,
00108              "(process:%u): %s%s: ",
00109              (guint) getpid (),
00110              query1,
00111              query3);
00112   fflush (stdout);
00113   
00114 #ifndef NATIVE_WIN32
00115   if (isatty(0) && isatty(1))
00116     fgets (buf, 8, stdin); 
00117   else
00118     strcpy (buf, "E\n");
00119 #else
00120   fgets (buf, 8, stdin); 
00121 #endif
00122 
00123   if ((buf[0] == 'E' || buf[0] == 'e')
00124       && buf[1] == '\n')
00125     _exit (0);
00126   else if ((buf[0] == 'P' || buf[0] == 'p')
00127            && buf[1] == '\n')
00128     return;
00129   else if (prg_name
00130            && (buf[0] == 'S' || buf[0] == 's')
00131            && buf[1] == '\n')
00132     {
00133       g_on_error_stack_trace (prg_name);
00134       goto retry;
00135     }
00136   else if ((buf[0] == 'H' || buf[0] == 'h')
00137            && buf[1] == '\n')
00138     {
00139       while (glib_on_error_halt)
00140         ;
00141       glib_on_error_halt = TRUE;
00142       return;
00143     }
00144   else
00145     goto retry;
00146 }

void g_on_error_stack_trace const gchar prg_name  ) 
 

Definition at line 149 of file gerror.c.

References glib_on_error_halt, NULL, stack_trace(), and TRUE.

Referenced by g_on_error_query().

00150 {
00151 #ifndef NATIVE_WIN32
00152   pid_t pid;
00153   gchar buf[16];
00154   gchar *args[4] = { "gdb", NULL, NULL, NULL };
00155 
00156   if (!prg_name)
00157     return;
00158 
00159   sprintf (buf, "%u", (guint) getpid ());
00160 
00161   args[1] = (gchar*) prg_name;
00162   args[2] = buf;
00163 
00164   pid = fork ();
00165   if (pid == 0)
00166     {
00167       stack_trace (args);
00168       _exit (0);
00169     }
00170   else if (pid == (pid_t) -1)
00171     {
00172       perror ("unable to fork gdb");
00173       return;
00174     }
00175   
00176   while (glib_on_error_halt)
00177     ;
00178   glib_on_error_halt = TRUE;
00179 #else
00180   abort ();
00181 #endif
00182 }

static void stack_trace char **  args  )  [static]
 

Definition at line 193 of file gerror.c.

References FALSE, NULL, SELECT_MASK, stack_trace_done, and stack_trace_sigchld().

Referenced by g_on_error_stack_trace().

00194 {
00195 #ifndef NATIVE_WIN32
00196   pid_t pid;
00197   int in_fd[2];
00198   int out_fd[2];
00199   SELECT_MASK fdset;
00200   SELECT_MASK readset;
00201   struct timeval tv;
00202   int sel, index, state;
00203   char buffer[256];
00204   char c;
00205 
00206   stack_trace_done = FALSE;
00207   signal (SIGCHLD, stack_trace_sigchld);
00208 
00209   if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
00210     {
00211       perror ("unable to open pipe");
00212       _exit (0);
00213     }
00214 
00215   pid = fork ();
00216   if (pid == 0)
00217     {
00218       close (0); dup (in_fd[0]);   /* set the stdin to the in pipe */
00219       close (1); dup (out_fd[1]);  /* set the stdout to the out pipe */
00220       close (2); dup (out_fd[1]);  /* set the stderr to the out pipe */
00221 
00222       execvp (args[0], args);      /* exec gdb */
00223       perror ("exec failed");
00224       _exit (0);
00225     }
00226   else if (pid == (pid_t) -1)
00227     {
00228       perror ("unable to fork");
00229       _exit (0);
00230     }
00231 
00232   FD_ZERO (&fdset);
00233   FD_SET (out_fd[0], &fdset);
00234 
00235   write (in_fd[1], "backtrace\n", 10);
00236   write (in_fd[1], "p x = 0\n", 8);
00237   write (in_fd[1], "quit\n", 5);
00238 
00239   index = 0;
00240   state = 0;
00241 
00242   while (1)
00243     {
00244       readset = fdset;
00245       tv.tv_sec = 1;
00246       tv.tv_usec = 0;
00247 
00248       sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
00249       if (sel == -1)
00250         break;
00251 
00252       if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
00253         {
00254           if (read (out_fd[0], &c, 1))
00255             {
00256               switch (state)
00257                 {
00258                 case 0:
00259                   if (c == '#')
00260                     {
00261                       state = 1;
00262                       index = 0;
00263                       buffer[index++] = c;
00264                     }
00265                   break;
00266                 case 1:
00267                   buffer[index++] = c;
00268                   if ((c == '\n') || (c == '\r'))
00269                     {
00270                       buffer[index] = 0;
00271                       fprintf (stdout, "%s", buffer);
00272                       state = 0;
00273                       index = 0;
00274                     }
00275                   break;
00276                 default:
00277                   break;
00278                 }
00279             }
00280         }
00281       else if (stack_trace_done)
00282         break;
00283     }
00284 
00285   close (in_fd[0]);
00286   close (in_fd[1]);
00287   close (out_fd[0]);
00288   close (out_fd[1]);
00289   _exit (0);
00290 #else
00291   abort ();
00292 #endif
00293 }

static void stack_trace_sigchld int  signum  )  [static]
 

Definition at line 187 of file gerror.c.

References stack_trace_done, and TRUE.

Referenced by stack_trace().

00188 {
00189   stack_trace_done = TRUE;
00190 }


Variable Documentation

volatile gboolean glib_on_error_halt = TRUE
 

Definition at line 83 of file gerror.c.

Referenced by g_on_error_query(), and g_on_error_stack_trace().

gboolean stack_trace_done = FALSE [static]
 

Definition at line 184 of file gerror.c.

Referenced by stack_trace(), and stack_trace_sigchld().


© sourcejam.com 2005-2008