1 /* Target-vector operations for controlling Unix child processes, for GDB.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include "frame.h" /* required by inferior.h */
31 child_prepare_to_store PARAMS ((void));
34 static int child_wait PARAMS ((int, struct target_waitstatus *));
35 #endif /* CHILD_WAIT */
37 static void child_open PARAMS ((char *, int));
40 child_files_info PARAMS ((struct target_ops *));
43 child_detach PARAMS ((char *, int));
46 child_attach PARAMS ((char *, int));
49 ptrace_me PARAMS ((void));
52 ptrace_him PARAMS ((int));
54 static void child_create_inferior PARAMS ((char *, char *, char **));
57 child_mourn_inferior PARAMS ((void));
60 child_can_run PARAMS ((void));
62 extern char **environ;
64 /* Forward declaration */
65 extern struct target_ops child_ops;
69 /* Wait for child to do something. Return pid of child, or -1 in case
70 of error; store status through argument pointer OURSTATUS. */
73 child_wait (pid, ourstatus)
75 struct target_waitstatus *ourstatus;
82 set_sigint_trap(); /* Causes SIGINT to be passed on to the
96 if (save_errno == EINTR)
98 fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
99 safe_strerror (save_errno));
100 /* Claim it exited with unknown signal. */
101 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
102 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
105 } while (pid != inferior_pid); /* Some other child died or stopped */
106 store_waitstatus (ourstatus, status);
109 #endif /* CHILD_WAIT */
111 /* Attach to process PID, then initialize for debugging it. */
114 child_attach (args, from_tty)
119 error_no_arg ("process-id to attach");
121 #ifndef ATTACH_DETACH
122 error ("Can't attach to a process on this machine.");
130 if (pid == getpid()) /* Trying to masturbate? */
131 error ("I refuse to debug myself!");
135 exec_file = (char *) get_exec_file (0);
138 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
139 target_pid_to_str (pid));
141 printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
143 gdb_flush (gdb_stdout);
148 push_target (&child_ops);
150 #endif /* ATTACH_DETACH */
154 /* Take a program previously attached to and detaches it.
155 The program resumes execution and will no longer stop
156 on signals, etc. We'd better not have left any breakpoints
157 in the program or it'll die when it hits one. For this
158 to work, it may be necessary for the process to have been
159 previously attached. It *might* work if the program was
160 started via the normal ptrace (PTRACE_TRACEME). */
163 child_detach (args, from_tty)
173 char *exec_file = get_exec_file (0);
176 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
177 target_pid_to_str (inferior_pid));
178 gdb_flush (gdb_stdout);
181 siggnal = atoi (args);
185 unpush_target (&child_ops);
188 error ("This version of Unix does not support detaching a process.");
192 /* Get ready to modify the registers array. On machines which store
193 individual registers, this doesn't need to do anything. On machines
194 which store all the registers in one fell swoop, this makes sure
195 that registers contains all the registers from the program being
199 child_prepare_to_store ()
201 #ifdef CHILD_PREPARE_TO_STORE
202 CHILD_PREPARE_TO_STORE ();
206 /* Print status information about what we're accessing. */
209 child_files_info (ignore)
210 struct target_ops *ignore;
212 printf_unfiltered ("\tUsing the running image of %s %s.\n",
213 attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
218 child_open (arg, from_tty)
222 error ("Use the \"run\" command to start a Unix child process.");
225 /* Stub function which causes the inferior that runs it, to be ptrace-able
226 by its parent process. */
231 /* "Trace me, Dr. Memory!" */
232 call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
235 /* Stub function which causes the GDB that runs it, to start ptrace-ing
236 the child process. */
242 push_target (&child_ops);
244 #ifdef START_INFERIOR_TRAPS_EXPECTED
245 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
247 /* One trap to exec the shell, one to exec the program being debugged. */
248 startup_inferior (2);
252 /* Start an inferior Unix child process and sets inferior_pid to its pid.
253 EXEC_FILE is the file to run.
254 ALLARGS is a string containing the arguments to the program.
255 ENV is the environment vector to pass. Errors reported with error(). */
258 child_create_inferior (exec_file, allargs, env)
263 fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL);
264 /* We are at the first instruction we care about. */
265 /* Pedal to the metal... */
266 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
270 child_mourn_inferior ()
272 unpush_target (&child_ops);
273 generic_mourn_inferior ();
282 struct target_ops child_ops = {
283 "child", /* to_shortname */
284 "Unix child process", /* to_longname */
285 "Unix child process (started by the \"run\" command).", /* to_doc */
286 child_open, /* to_open */
288 child_attach, /* to_attach */
289 child_detach, /* to_detach */
290 child_resume, /* to_resume */
291 child_wait, /* to_wait */
292 fetch_inferior_registers, /* to_fetch_registers */
293 store_inferior_registers, /* to_store_registers */
294 child_prepare_to_store, /* to_prepare_to_store */
295 child_xfer_memory, /* to_xfer_memory */
296 child_files_info, /* to_files_info */
297 memory_insert_breakpoint, /* to_insert_breakpoint */
298 memory_remove_breakpoint, /* to_remove_breakpoint */
299 terminal_init_inferior, /* to_terminal_init */
300 terminal_inferior, /* to_terminal_inferior */
301 terminal_ours_for_output, /* to_terminal_ours_for_output */
302 terminal_ours, /* to_terminal_ours */
303 child_terminal_info, /* to_terminal_info */
304 kill_inferior, /* to_kill */
306 0, /* to_lookup_symbol */
307 child_create_inferior, /* to_create_inferior */
308 child_mourn_inferior, /* to_mourn_inferior */
309 child_can_run, /* to_can_run */
310 0, /* to_notice_signals */
311 process_stratum, /* to_stratum */
313 1, /* to_has_all_memory */
314 1, /* to_has_memory */
315 1, /* to_has_stack */
316 1, /* to_has_registers */
317 1, /* to_has_execution */
319 0, /* sections_end */
320 OPS_MAGIC /* to_magic */
324 _initialize_inftarg ()
326 add_target (&child_ops);