Fri Sep 25 18:18:52 1992 Ian Lance Taylor (ian@cygnus.com)
[deliverable/binutils-gdb.git] / gdb / inftarg.c
CommitLineData
310cc570
RP
1/* This file inplements the host independent child process statum.
2
3 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
bd5635a1
RP
4 Contributed by Cygnus Support.
5
6This file is part of GDB.
7
dcc8abce 8This program is free software; you can redistribute it and/or modify
bd5635a1 9it under the terms of the GNU General Public License as published by
dcc8abce
JG
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
bd5635a1 12
dcc8abce 13This program is distributed in the hope that it will be useful,
bd5635a1
RP
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
dcc8abce
JG
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
bd5635a1 21
bd5635a1 22#include "defs.h"
bd5635a1
RP
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 "ieee-float.h" /* Required by REGISTER_CONVERT_TO_XXX */
310cc570
RP
29#include "terminal.h" /* For #ifdef TIOCGPGRP and new_tty */
30
31#include <signal.h>
32
33#ifdef SET_STACK_LIMIT_HUGE
34#include <sys/time.h>
35#include <sys/resource.h>
36
37extern int original_stack_limit;
38#endif /* SET_STACK_LIMIT_HUGE */
bd5635a1 39
dcc8abce
JG
40static void
41child_prepare_to_store PARAMS ((void));
42
43static int
44child_wait PARAMS ((int *));
45
46static void
47child_open PARAMS ((char *, int));
48
49static void
50child_files_info PARAMS ((struct target_ops *));
51
52static void
53child_detach PARAMS ((char *, int));
bd5635a1 54
310cc570
RP
55static void
56child_attach PARAMS ((char *, int));
57
58static void
59child_create_inferior PARAMS ((char *, char *, char **));
60
61static void
62child_mourn_inferior PARAMS ((void));
63
64extern char **environ;
65
bd5635a1
RP
66/* Forward declaration */
67extern struct target_ops child_ops;
68
69/* Wait for child to do something. Return pid of child, or -1 in case
70 of error; store status through argument pointer STATUS. */
71
dcc8abce 72static int
bd5635a1
RP
73child_wait (status)
74 int *status;
75{
76 int pid;
77
78 do {
dcc8abce
JG
79#ifdef USE_PROC_FS
80 pid = proc_wait (status);
81#else
bd5635a1 82 pid = wait (status);
dcc8abce 83#endif
bd5635a1
RP
84 if (pid == -1) /* No more children to wait for */
85 {
86 fprintf (stderr, "Child process unexpectedly missing.\n");
87 *status = 42; /* Claim it exited with signal 42 */
88 return -1;
89 }
90 } while (pid != inferior_pid); /* Some other child died or stopped */
91 return pid;
92}
93
94
310cc570
RP
95/* Attach to process PID, then initialize for debugging it
96 and wait for the trace-trap that results from attaching. */
97
98static void
99child_attach (args, from_tty)
100 char *args;
101 int from_tty;
102{
103 char *exec_file;
104 int pid;
105
106 dont_repeat();
107
108 if (!args)
109 error_no_arg ("process-id to attach");
110
111#ifndef ATTACH_DETACH
112 error ("Can't attach to a process on this machine.");
113#else
114 pid = atoi (args);
115
116 if (pid == getpid()) /* Trying to masturbate? */
117 error ("I refuse to debug myself!");
118
119 if (target_has_execution)
120 {
121 if (query ("A program is being debugged already. Kill it? "))
122 target_kill ();
123 else
124 error ("Inferior not killed.");
125 }
126
127 if (from_tty)
128 {
129 exec_file = (char *) get_exec_file (0);
130
131 if (exec_file)
132 printf ("Attaching program `%s', pid %d\n", exec_file, pid);
133 else
134 printf ("Attaching pid %d\n", pid);
135
136 fflush (stdout);
137 }
138
139 attach (pid);
140 inferior_pid = pid;
141 push_target (&child_ops);
142
143 mark_breakpoints_out ();
144 target_terminal_init ();
145 clear_proceed_status ();
146 stop_soon_quietly = 1;
147 /*proceed (-1, 0, -2);*/
148 target_terminal_inferior ();
149 wait_for_inferior ();
150#ifdef SOLIB_ADD
151 SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0);
152#endif
153 normal_stop ();
154#endif /* ATTACH_DETACH */
155}
156
bd5635a1
RP
157/*
158 * child_detach()
159 * takes a program previously attached to and detaches it.
160 * The program resumes execution and will no longer stop
161 * on signals, etc. We better not have left any breakpoints
162 * in the program or it'll die when it hits one. For this
163 * to work, it may be necessary for the process to have been
164 * previously attached. It *might* work if the program was
165 * started via the normal ptrace (PTRACE_TRACEME).
166 */
167
168static void
169child_detach (args, from_tty)
170 char *args;
171 int from_tty;
172{
173 int siggnal = 0;
174
175#ifdef ATTACH_DETACH
176 if (from_tty)
177 {
178 char *exec_file = get_exec_file (0);
179 if (exec_file == 0)
180 exec_file = "";
181 printf ("Detaching program: %s pid %d\n",
182 exec_file, inferior_pid);
183 fflush (stdout);
184 }
185 if (args)
186 siggnal = atoi (args);
187
188 detach (siggnal);
189 inferior_pid = 0;
190 unpush_target (&child_ops); /* Pop out of handling an inferior */
191#else
192 error ("This version of Unix does not support detaching a process.");
193#endif
194}
195
196/* Get ready to modify the registers array. On machines which store
197 individual registers, this doesn't need to do anything. On machines
198 which store all the registers in one fell swoop, this makes sure
199 that registers contains all the registers from the program being
200 debugged. */
201
dcc8abce 202static void
bd5635a1
RP
203child_prepare_to_store ()
204{
205#ifdef CHILD_PREPARE_TO_STORE
206 CHILD_PREPARE_TO_STORE ();
207#endif
208}
209
bd5635a1
RP
210/* Print status information about what we're accessing. */
211
212static void
dcc8abce
JG
213child_files_info (ignore)
214 struct target_ops *ignore;
bd5635a1
RP
215{
216 printf ("\tUsing the running image of %s process %d.\n",
217 attach_flag? "attached": "child", inferior_pid);
218}
219
e1ce8aa5 220/* ARGSUSED */
70dcc196
JK
221static void
222child_open (arg, from_tty)
223 char *arg;
224 int from_tty;
225{
226 error ("Use the \"run\" command to start a Unix child process.");
227}
228
310cc570
RP
229/* Start an inferior Unix child process and sets inferior_pid to its pid.
230 EXEC_FILE is the file to run.
231 ALLARGS is a string containing the arguments to the program.
232 ENV is the environment vector to pass. Errors reported with error(). */
233
234#ifndef SHELL_FILE
235#define SHELL_FILE "/bin/sh"
236#endif
237
238static void
239child_create_inferior (exec_file, allargs, env)
240 char *exec_file;
241 char *allargs;
242 char **env;
243{
244 int pid;
245 char *shell_command;
246 char *shell_file;
247 static char default_shell_file[] = SHELL_FILE;
248 int len;
249 int pending_execs;
250 /* Set debug_fork then attach to the child while it sleeps, to debug. */
251 static int debug_fork = 0;
252 /* This is set to the result of setpgrp, which if vforked, will be visible
253 to you in the parent process. It's only used by humans for debugging. */
254 static int debug_setpgrp = 657473;
255 char **save_our_env;
256
257 /* If no exec file handed to us, get it from the exec-file command -- with
258 a good, common error message if none is specified. */
259 if (exec_file == 0)
260 exec_file = get_exec_file(1);
261
262 /* The user might want tilde-expansion, and in general probably wants
263 the program to behave the same way as if run from
264 his/her favorite shell. So we let the shell run it for us.
265 FIXME, this should probably search the local environment (as
266 modified by the setenv command), not the env gdb inherited. */
267 shell_file = getenv ("SHELL");
268 if (shell_file == NULL)
269 shell_file = default_shell_file;
270
271 len = 5 + strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop*/ 10;
272 /* If desired, concat something onto the front of ALLARGS.
273 SHELL_COMMAND is the result. */
274#ifdef SHELL_COMMAND_CONCAT
275 shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + len);
276 strcpy (shell_command, SHELL_COMMAND_CONCAT);
277#else
278 shell_command = (char *) alloca (len);
279 shell_command[0] = '\0';
280#endif
281 strcat (shell_command, "exec ");
282 strcat (shell_command, exec_file);
283 strcat (shell_command, " ");
284 strcat (shell_command, allargs);
285
286 /* exec is said to fail if the executable is open. */
287 close_exec_file ();
288
289 /* Retain a copy of our environment variables, since the child will
290 replace the value of environ and if we're vforked, we have to
291 restore it. */
292 save_our_env = environ;
293
294 /* Tell the terminal handling subsystem what tty we plan to run on;
295 it will just record the information for later. */
296
297 new_tty_prefork (inferior_io_terminal);
298
299 /* It is generally good practice to flush any possible pending stdio
300 output prior to doing a fork, to avoid the possibility of both the
301 parent and child flushing the same data after the fork. */
302
303 fflush (stdout);
304 fflush (stderr);
305
306#if defined(USG) && !defined(HAVE_VFORK)
307 pid = fork ();
308#else
309 if (debug_fork)
310 pid = fork ();
311 else
312 pid = vfork ();
313#endif
314
315 if (pid < 0)
316 perror_with_name ("vfork");
317
318 if (pid == 0)
319 {
320 if (debug_fork)
321 sleep (debug_fork);
322
323#ifdef TIOCGPGRP
324 /* Run inferior in a separate process group. */
325#ifdef NEED_POSIX_SETPGID
326 debug_setpgrp = setpgid (0, 0);
327#else
328#if defined(USG) && !defined(SETPGRP_ARGS)
329 debug_setpgrp = setpgrp ();
330#else
331 debug_setpgrp = setpgrp (getpid (), getpid ());
332#endif /* USG */
333#endif /* NEED_POSIX_SETPGID */
334 if (debug_setpgrp == -1)
335 perror("setpgrp failed in child");
336#endif /* TIOCGPGRP */
337
338#ifdef SET_STACK_LIMIT_HUGE
339 /* Reset the stack limit back to what it was. */
340 {
341 struct rlimit rlim;
342
343 getrlimit (RLIMIT_STACK, &rlim);
344 rlim.rlim_cur = original_stack_limit;
345 setrlimit (RLIMIT_STACK, &rlim);
346 }
347#endif /* SET_STACK_LIMIT_HUGE */
348
349 /* Ask the tty subsystem to switch to the one we specified earlier
350 (or to share the current terminal, if none was specified). */
351
352 new_tty ();
353
354 /* Changing the signal handlers for the inferior after
355 a vfork can also change them for the superior, so we don't mess
356 with signals here. See comments in
357 initialize_signals for how we get the right signal handlers
358 for the inferior. */
359
360#ifdef USE_PROC_FS
361 /* Use SVR4 /proc interface */
362 proc_set_exec_trap ();
363#else
364 /* "Trace me, Dr. Memory!" */
365 call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
366#endif
367
368 /* There is no execlpe call, so we have to set the environment
369 for our child in the global variable. If we've vforked, this
370 clobbers the parent, but environ is restored a few lines down
371 in the parent. By the way, yes we do need to look down the
372 path to find $SHELL. Rich Pixley says so, and I agree. */
373 environ = env;
374 execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
375
376 fprintf (stderr, "Cannot exec %s: %s.\n", shell_file,
377 safe_strerror (errno));
378 fflush (stderr);
379 _exit (0177);
380 }
381
382 /* Restore our environment in case a vforked child clob'd it. */
383 environ = save_our_env;
384
385 /* Now that we have a child process, make it our target. */
386 push_target (&child_ops);
387
388#ifdef CREATE_INFERIOR_HOOK
389 CREATE_INFERIOR_HOOK (pid);
390#endif
391
392/* The process was started by the fork that created it,
393 but it will have stopped one instruction after execing the shell.
394 Here we must get it up to actual execution of the real program. */
395
396 inferior_pid = pid; /* Needed for wait_for_inferior stuff below */
397
398 clear_proceed_status ();
399
400 /* We will get a trace trap after one instruction.
401 Continue it automatically. Eventually (after shell does an exec)
402 it will get another trace trap. Then insert breakpoints and continue. */
403
404#ifdef START_INFERIOR_TRAPS_EXPECTED
405 pending_execs = START_INFERIOR_TRAPS_EXPECTED;
406#else
407 pending_execs = 2;
408#endif
409
410 init_wait_for_inferior ();
411
412 /* Set up the "saved terminal modes" of the inferior
413 based on what modes we are starting it with. */
414 target_terminal_init ();
415
416 /* Install inferior's terminal modes. */
417 target_terminal_inferior ();
418
419 while (1)
420 {
421 stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */
422 wait_for_inferior ();
423 if (stop_signal != SIGTRAP)
424 {
425 /* Let shell child handle its own signals in its own way */
426 /* FIXME, what if child has exit()ed? Must exit loop somehow */
427 resume (0, stop_signal);
428 }
429 else
430 {
431 /* We handle SIGTRAP, however; it means child did an exec. */
432 if (0 == --pending_execs)
433 break;
434 resume (0, 0); /* Just make it go on */
435 }
436 }
437 stop_soon_quietly = 0;
438
439 /* We are now in the child process of interest, having exec'd the
440 correct program, and are poised at the first instruction of the
441 new program. */
442#ifdef SOLIB_CREATE_INFERIOR_HOOK
443 SOLIB_CREATE_INFERIOR_HOOK (pid);
444#endif
445
446 /* Pedal to the metal. Away we go. */
447 proceed ((CORE_ADDR) -1, 0, 0);
448}
449
450static void
451child_mourn_inferior ()
452{
453 unpush_target (&child_ops);
454 generic_mourn_inferior ();
455}
456
457static int
458child_can_run ()
459{
460 return(1);
461}
462
bd5635a1 463struct target_ops child_ops = {
dcc8abce
JG
464 "child", /* to_shortname */
465 "Unix child process", /* to_longname */
466 "Unix child process (started by the \"run\" command).", /* to_doc */
467 child_open, /* to_open */
468 0, /* to_close */
469 child_attach, /* to_attach */
470 child_detach, /* to_detach */
471 child_resume, /* to_resume */
472 child_wait, /* to_wait */
473 fetch_inferior_registers, /* to_fetch_registers */
474 store_inferior_registers, /* to_store_registers */
475 child_prepare_to_store, /* to_prepare_to_store */
476 child_xfer_memory, /* to_xfer_memory */
477 child_files_info, /* to_files_info */
478 memory_insert_breakpoint, /* to_insert_breakpoint */
479 memory_remove_breakpoint, /* to_remove_breakpoint */
480 terminal_init_inferior, /* to_terminal_init */
481 terminal_inferior, /* to_terminal_inferior */
482 terminal_ours_for_output, /* to_terminal_ours_for_output */
483 terminal_ours, /* to_terminal_ours */
484 child_terminal_info, /* to_terminal_info */
485 kill_inferior, /* to_kill */
486 0, /* to_load */
487 0, /* to_lookup_symbol */
488 child_create_inferior, /* to_create_inferior */
489 child_mourn_inferior, /* to_mourn_inferior */
310cc570 490 child_can_run, /* to_can_run */
dcc8abce
JG
491 process_stratum, /* to_stratum */
492 0, /* to_next */
493 1, /* to_has_all_memory */
494 1, /* to_has_memory */
495 1, /* to_has_stack */
496 1, /* to_has_registers */
497 1, /* to_has_execution */
498 0, /* sections */
499 0, /* sections_end */
500 OPS_MAGIC /* to_magic */
bd5635a1
RP
501};
502
503void
504_initialize_inftarg ()
505{
506 add_target (&child_ops);
507}
This page took 0.089255 seconds and 4 git commands to generate.