]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gdb/gdb/inftarg.c
This commit was generated by cvs2svn to compensate for changes in r37510,
[FreeBSD/FreeBSD.git] / contrib / gdb / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Support.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "frame.h"  /* required by inferior.h */
24 #include "inferior.h"
25 #include "target.h"
26 #include "wait.h"
27 #include "gdbcore.h"
28 #include "command.h"
29 #include <signal.h>
30 #include <sys/types.h>
31 #include <fcntl.h>
32
33 static void
34 child_prepare_to_store PARAMS ((void));
35
36 #ifndef CHILD_WAIT
37 static int child_wait PARAMS ((int, struct target_waitstatus *));
38 #endif /* CHILD_WAIT */
39
40 static void child_open PARAMS ((char *, int));
41
42 static void
43 child_files_info PARAMS ((struct target_ops *));
44
45 static void
46 child_detach PARAMS ((char *, int));
47
48 static void
49 child_attach PARAMS ((char *, int));
50
51 static void
52 ptrace_me PARAMS ((void));
53
54 static void
55 ptrace_him PARAMS ((int));
56
57 static void child_create_inferior PARAMS ((char *, char *, char **));
58
59 static void
60 child_mourn_inferior PARAMS ((void));
61
62 static int
63 child_can_run PARAMS ((void));
64
65 static int child_thread_alive PARAMS ((int));
66
67 extern char **environ;
68
69 /* Forward declaration */
70 extern struct target_ops child_ops;
71
72 static int
73 proc_wait (pid, status)
74      int pid;
75      int *status;
76 {
77 #ifndef __GO32__
78   return wait (status);
79 #endif
80 }
81
82 #ifndef CHILD_WAIT
83
84 /* Wait for child to do something.  Return pid of child, or -1 in case
85    of error; store status through argument pointer OURSTATUS.  */
86
87 static int
88 child_wait (pid, ourstatus)
89      int pid;
90      struct target_waitstatus *ourstatus;
91 {
92   int save_errno;
93   int status;
94
95   do {
96     set_sigint_trap();  /* Causes SIGINT to be passed on to the
97                            attached process. */
98     set_sigio_trap ();
99
100     pid = proc_wait (inferior_pid, &status);
101     save_errno = errno;
102
103     clear_sigio_trap ();
104
105     clear_sigint_trap();
106
107     if (pid == -1)
108       {
109         if (save_errno == EINTR)
110           continue;
111         fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
112                  safe_strerror (save_errno));
113         /* Claim it exited with unknown signal.  */
114         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
115         ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
116         return -1;
117       }
118   } while (pid != inferior_pid); /* Some other child died or stopped */
119   store_waitstatus (ourstatus, status);
120   return pid;
121 }
122 #endif /* CHILD_WAIT */
123
124 #ifndef CHILD_THREAD_ALIVE
125
126 /* Check to see if the given thread is alive.
127
128    FIXME: Is kill() ever the right way to do this?  I doubt it, but
129    for now we're going to try and be compatable with the old thread
130    code.  */
131 static int
132 child_thread_alive (pid)
133      int pid;
134 {
135   return (kill (pid, 0) != -1);
136 }
137
138 #endif
139
140 /* Attach to process PID, then initialize for debugging it.  */
141
142 static void
143 child_attach (args, from_tty)
144      char *args;
145      int from_tty;
146 {
147   if (!args)
148     error_no_arg ("process-id to attach");
149
150 #ifndef ATTACH_DETACH
151   error ("Can't attach to a process on this machine.");
152 #else
153   {
154     char *exec_file;
155     int pid;
156
157     pid = atoi (args);
158
159     if (pid == getpid())                /* Trying to masturbate? */
160       error ("I refuse to debug myself!");
161
162     if (from_tty)
163       {
164         exec_file = (char *) get_exec_file (0);
165
166         if (exec_file)
167           printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
168                   target_pid_to_str (pid));
169         else
170           printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
171
172         gdb_flush (gdb_stdout);
173       }
174
175     attach (pid);
176     inferior_pid = pid;
177     push_target (&child_ops);
178   }
179 #endif  /* ATTACH_DETACH */
180 }
181
182
183 /* Take a program previously attached to and detaches it.
184    The program resumes execution and will no longer stop
185    on signals, etc.  We'd better not have left any breakpoints
186    in the program or it'll die when it hits one.  For this
187    to work, it may be necessary for the process to have been
188    previously attached.  It *might* work if the program was
189    started via the normal ptrace (PTRACE_TRACEME).  */
190
191 static void
192 child_detach (args, from_tty)
193      char *args;
194      int from_tty;
195 {
196 #ifdef ATTACH_DETACH
197   {
198     int siggnal = 0;
199
200     if (from_tty)
201       {
202         char *exec_file = get_exec_file (0);
203         if (exec_file == 0)
204           exec_file = "";
205         printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
206                 target_pid_to_str (inferior_pid));
207         gdb_flush (gdb_stdout);
208       }
209     if (args)
210       siggnal = atoi (args);
211
212     detach (siggnal);
213     inferior_pid = 0;
214     unpush_target (&child_ops);
215   }
216 #else
217   error ("This version of Unix does not support detaching a process.");
218 #endif
219 }
220
221 /* Get ready to modify the registers array.  On machines which store
222    individual registers, this doesn't need to do anything.  On machines
223    which store all the registers in one fell swoop, this makes sure
224    that registers contains all the registers from the program being
225    debugged.  */
226
227 static void
228 child_prepare_to_store ()
229 {
230 #ifdef CHILD_PREPARE_TO_STORE
231   CHILD_PREPARE_TO_STORE ();
232 #endif
233 }
234
235 /* Print status information about what we're accessing.  */
236
237 static void
238 child_files_info (ignore)
239      struct target_ops *ignore;
240 {
241   printf_unfiltered ("\tUsing the running image of %s %s.\n",
242           attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
243 }
244
245 /* ARGSUSED */
246 static void
247 child_open (arg, from_tty)
248      char *arg;
249      int from_tty;
250 {
251   error ("Use the \"run\" command to start a Unix child process.");
252 }
253
254 /* Stub function which causes the inferior that runs it, to be ptrace-able
255    by its parent process.  */
256
257 static void
258 ptrace_me ()
259 {
260   /* "Trace me, Dr. Memory!" */
261   call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
262 }
263
264 /* Stub function which causes the GDB that runs it, to start ptrace-ing
265    the child process.  */
266
267 static void
268 ptrace_him (pid)
269      int pid;
270 {
271   push_target (&child_ops);
272
273 #ifdef START_INFERIOR_TRAPS_EXPECTED
274   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
275 #else
276   /* One trap to exec the shell, one to exec the program being debugged.  */
277   startup_inferior (2);
278 #endif
279 }
280
281 /* Start an inferior Unix child process and sets inferior_pid to its pid.
282    EXEC_FILE is the file to run.
283    ALLARGS is a string containing the arguments to the program.
284    ENV is the environment vector to pass.  Errors reported with error().  */
285
286 static void
287 child_create_inferior (exec_file, allargs, env)
288      char *exec_file;
289      char *allargs;
290      char **env;
291 {
292   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL);
293   /* We are at the first instruction we care about.  */
294   /* Pedal to the metal... */
295   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
296 }
297
298 static void
299 child_mourn_inferior ()
300 {
301   unpush_target (&child_ops);
302   proc_remove_foreign (inferior_pid);
303   generic_mourn_inferior ();
304 }
305
306 static int
307 child_can_run ()
308 {
309   return(1);
310 }
311
312 /* Send a SIGINT to the process group.  This acts just like the user typed a
313    ^C on the controlling terminal.
314
315    XXX - This may not be correct for all systems.  Some may want to use
316    killpg() instead of kill (-pgrp). */
317
318 void
319 child_stop ()
320 {
321   extern pid_t inferior_process_group;
322
323   kill (-inferior_process_group, SIGINT);
324 }
325 \f
326 struct target_ops child_ops = {
327   "child",                      /* to_shortname */
328   "Unix child process",         /* to_longname */
329   "Unix child process (started by the \"run\" command).",       /* to_doc */
330   child_open,                   /* to_open */
331   0,                            /* to_close */
332   child_attach,                 /* to_attach */
333   child_detach,                 /* to_detach */
334   child_resume,                 /* to_resume */
335   child_wait,                   /* to_wait */
336   fetch_inferior_registers,     /* to_fetch_registers */
337   store_inferior_registers,     /* to_store_registers */
338   child_prepare_to_store,       /* to_prepare_to_store */
339   child_xfer_memory,            /* to_xfer_memory */
340   child_files_info,             /* to_files_info */
341   memory_insert_breakpoint,     /* to_insert_breakpoint */
342   memory_remove_breakpoint,     /* to_remove_breakpoint */
343   terminal_init_inferior,       /* to_terminal_init */
344   terminal_inferior,            /* to_terminal_inferior */
345   terminal_ours_for_output,     /* to_terminal_ours_for_output */
346   terminal_ours,                /* to_terminal_ours */
347   child_terminal_info,          /* to_terminal_info */
348   kill_inferior,                /* to_kill */
349   0,                            /* to_load */
350   0,                            /* to_lookup_symbol */
351   child_create_inferior,        /* to_create_inferior */
352   child_mourn_inferior,         /* to_mourn_inferior */
353   child_can_run,                /* to_can_run */
354   0,                            /* to_notice_signals */
355   child_thread_alive,           /* to_thread_alive */
356   child_stop,                   /* to_stop */
357   process_stratum,              /* to_stratum */
358   0,                            /* to_next */
359   1,                            /* to_has_all_memory */
360   1,                            /* to_has_memory */
361   1,                            /* to_has_stack */
362   1,                            /* to_has_registers */
363   1,                            /* to_has_execution */
364   0,                            /* to_sections */
365   0,                            /* to_sections_end */
366   OPS_MAGIC                     /* to_magic */
367 };
368
369 void
370 _initialize_inftarg ()
371 {
372 #ifdef HAVE_OPTIONAL_PROC_FS
373   char procname[32];
374   int fd;
375
376   /* If we have an optional /proc filesystem (e.g. under OSF/1),
377      don't add ptrace support if we can access the running GDB via /proc.  */
378 #ifndef PROC_NAME_FMT
379 #define PROC_NAME_FMT "/proc/%05d"
380 #endif
381   sprintf (procname, PROC_NAME_FMT, getpid ());
382   if ((fd = open (procname, O_RDONLY)) >= 0)
383     {
384       close (fd);
385       return;
386     }
387 #endif
388
389   add_target (&child_ops);
390 }