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.
23 #include <sys/times.h>
24 #include <sys/types.h>
30 #ifdef HAVE_SYS_SELECT_H
31 #include <sys/select.h>
32 #endif /* HAVE_SYS_SELECT_H */
35 #include <string.h> /* for bzero on BSD systems */
43 # define SELECT_MASK fd_set
49 # define SELECT_MASK void
51 # define SELECT_MASK int
56 static int do_query (char *prompt);
57 static void debug (char *progname, int method);
58 static void stack_trace (char **);
59 static void stack_trace_sigchld (int);
62 static int stack_trace_done;
65 g_debug (char *progname)
69 fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
72 fgets (buf, 32, stdin);
73 if (strcmp (buf, "n\n") == 0)
75 else if (strcmp (buf, "s\n") == 0)
76 debug (progname, STACK_TRACE);
77 else if (strcmp (buf, "a\n") == 0)
78 debug (progname, INTERACTIVE);
84 g_attach_process (char *progname, int query)
86 if (!query || do_query ("attach to process"))
87 debug (progname, INTERACTIVE);
91 g_stack_trace (char *progname, int query)
93 if (!query || do_query ("print stack trace"))
94 debug (progname, STACK_TRACE);
98 do_query (char *prompt)
102 fprintf (stdout, "%s (y/n) ", prompt);
105 fgets (buf, 32, stdin);
106 if ((strcmp (buf, "yes\n") == 0) ||
107 (strcmp (buf, "y\n") == 0) ||
108 (strcmp (buf, "YES\n") == 0) ||
109 (strcmp (buf, "Y\n") == 0))
116 debug (char *progname,
121 char *args[4] = { "gdb", NULL, NULL, NULL };
124 sprintf (buf, "%d", (int) getpid ());
132 fprintf (stdout, "pid: %s\n", buf);
141 else if (pid == (pid_t) -1)
143 perror ("could not fork");
155 stack_trace (char **args)
163 int sel, index, state;
167 stack_trace_done = 0;
168 signal (SIGCHLD, stack_trace_sigchld);
170 if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
172 perror ("could open pipe");
179 close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
180 close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
181 close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
183 execvp (args[0], args); /* exec gdb */
184 perror ("exec failed");
187 else if (pid == (pid_t) -1)
189 perror ("could not fork");
194 FD_SET (out_fd[0], &fdset);
196 write (in_fd[1], "backtrace\n", 10);
197 write (in_fd[1], "p x = 0\n", 8);
198 write (in_fd[1], "quit\n", 5);
209 sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
213 if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
215 if (read (out_fd[0], &c, 1))
229 if ((c == '\n') || (c == '\r'))
232 fprintf (stdout, "%s", buffer);
242 else if (stack_trace_done)
254 stack_trace_sigchld (int signum)
256 stack_trace_done = 1;