1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sys/times.h>
23 #include <sys/types.h>
29 #ifdef HAVE_SYS_SELECT_H
30 #include <sys/select.h>
31 #endif /* HAVE_SYS_SELECT_H */
34 #include <string.h> /* for bzero on BSD systems */
42 # define SELECT_MASK fd_set
48 # define SELECT_MASK void
50 # define SELECT_MASK int
55 static int do_query (char *prompt);
56 static void debug (char *progname, int method);
57 static void stack_trace (char **);
58 static void stack_trace_sigchld (int);
61 static int stack_trace_done;
64 g_debug (char *progname)
68 fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
71 fgets (buf, 32, stdin);
72 if (strcmp (buf, "n\n") == 0)
74 else if (strcmp (buf, "s\n") == 0)
75 debug (progname, STACK_TRACE);
76 else if (strcmp (buf, "a\n") == 0)
77 debug (progname, INTERACTIVE);
83 g_attach_process (char *progname, int query)
85 if (!query || do_query ("attach to process"))
86 debug (progname, INTERACTIVE);
90 g_stack_trace (char *progname, int query)
92 if (!query || do_query ("print stack trace"))
93 debug (progname, STACK_TRACE);
97 do_query (char *prompt)
101 fprintf (stdout, "%s (y/n) ", prompt);
104 fgets (buf, 32, stdin);
105 if ((strcmp (buf, "yes\n") == 0) ||
106 (strcmp (buf, "y\n") == 0) ||
107 (strcmp (buf, "YES\n") == 0) ||
108 (strcmp (buf, "Y\n") == 0))
115 debug (char *progname,
120 char *args[4] = { "gdb", NULL, NULL, NULL };
123 sprintf (buf, "%d", (int) getpid ());
131 fprintf (stdout, "pid: %s\n", buf);
140 else if (pid == (pid_t) -1)
142 perror ("could not fork");
154 stack_trace (char **args)
162 int sel, index, state;
166 stack_trace_done = 0;
167 signal (SIGCHLD, stack_trace_sigchld);
169 if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
171 perror ("could open pipe");
178 close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
179 close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
180 close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
182 execvp (args[0], args); /* exec gdb */
183 perror ("exec failed");
186 else if (pid == (pid_t) -1)
188 perror ("could not fork");
193 FD_SET (out_fd[0], &fdset);
195 write (in_fd[1], "backtrace\n", 10);
196 write (in_fd[1], "p x = 0\n", 8);
197 write (in_fd[1], "quit\n", 5);
208 sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
212 if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
214 if (read (out_fd[0], &c, 1))
228 if ((c == '\n') || (c == '\r'))
231 fprintf (stdout, "%s", buffer);
241 else if (stack_trace_done)
253 stack_trace_sigchld (int signum)
255 stack_trace_done = 1;