* value.c (value_virtual_fn_field): Handle the situation where
[deliverable/binutils-gdb.git] / gdb / inftarg.c
CommitLineData
3aa6856a 1/* Target-vector operations for controlling Unix child processes, for GDB.
4ef1f467
DT
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
3 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 19along with this program; if not, write to the Free Software
4ef1f467 20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
bd5635a1 26#include "gdbcore.h"
100f92e2 27#include "command.h"
310cc570 28#include <signal.h>
4ef1f467
DT
29#include <sys/types.h>
30#include <fcntl.h>
31
32#ifdef HAVE_WAIT_H
33# include <wait.h>
34#else
35# ifdef HAVE_SYS_WAIT_H
36# include <sys/wait.h>
37# endif
38#endif
39
40/* "wait.h" fills in the gaps left by <wait.h> */
41#include "wait.h"
310cc570 42
dcc8abce
JG
43static void
44child_prepare_to_store PARAMS ((void));
45
de43d7d0 46#ifndef CHILD_WAIT
429f1c9f 47static int child_wait PARAMS ((int, struct target_waitstatus *));
de43d7d0 48#endif /* CHILD_WAIT */
dcc8abce 49
429f1c9f 50static void child_open PARAMS ((char *, int));
dcc8abce
JG
51
52static void
53child_files_info PARAMS ((struct target_ops *));
54
55static void
56child_detach PARAMS ((char *, int));
bd5635a1 57
310cc570
RP
58static void
59child_attach PARAMS ((char *, int));
60
de43d7d0
SG
61static void
62ptrace_me PARAMS ((void));
63
4ef1f467 64static int
de43d7d0
SG
65ptrace_him PARAMS ((int));
66
429f1c9f 67static void child_create_inferior PARAMS ((char *, char *, char **));
310cc570
RP
68
69static void
70child_mourn_inferior PARAMS ((void));
71
3aa6856a
JG
72static int
73child_can_run PARAMS ((void));
74
4ef1f467
DT
75static int
76proc_wait PARAMS ((int, int*));
77
78static void
79child_stop PARAMS ((void));
80
81#ifndef CHILD_THREAD_ALIVE
82static int child_thread_alive PARAMS ((int));
83#endif
84
310cc570
RP
85extern char **environ;
86
bd5635a1
RP
87/* Forward declaration */
88extern struct target_ops child_ops;
89
4ef1f467
DT
90int child_suppress_run = 0; /* Non-zero if inftarg should pretend not to
91 be a runnable target. Used by targets
92 that can sit atop inftarg, such as HPUX
93 thread support. */
94static int
95proc_wait (pid, status)
96 int pid;
97 int *status;
98{
99#ifndef __GO32__
100 return wait (status);
101#endif
102}
103
de43d7d0
SG
104#ifndef CHILD_WAIT
105
bd5635a1 106/* Wait for child to do something. Return pid of child, or -1 in case
67ac9759 107 of error; store status through argument pointer OURSTATUS. */
bd5635a1 108
dcc8abce 109static int
67ac9759 110child_wait (pid, ourstatus)
de43d7d0 111 int pid;
67ac9759 112 struct target_waitstatus *ourstatus;
bd5635a1 113{
de43d7d0 114 int save_errno;
67ac9759 115 int status;
bd5635a1
RP
116
117 do {
4ef1f467
DT
118 set_sigint_trap(); /* Causes SIGINT to be passed on to the
119 attached process. */
429f1c9f
JK
120 set_sigio_trap ();
121
4ef1f467 122 pid = proc_wait (inferior_pid, &status);
de43d7d0
SG
123 save_errno = errno;
124
429f1c9f
JK
125 clear_sigio_trap ();
126
4ef1f467 127 clear_sigint_trap();
de43d7d0
SG
128
129 if (pid == -1)
bd5635a1 130 {
de43d7d0
SG
131 if (save_errno == EINTR)
132 continue;
67ac9759 133 fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
de43d7d0 134 safe_strerror (save_errno));
67ac9759
JK
135 /* Claim it exited with unknown signal. */
136 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
137 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
bd5635a1
RP
138 return -1;
139 }
140 } while (pid != inferior_pid); /* Some other child died or stopped */
67ac9759 141 store_waitstatus (ourstatus, status);
bd5635a1
RP
142 return pid;
143}
de43d7d0 144#endif /* CHILD_WAIT */
bd5635a1 145
4ef1f467
DT
146#ifndef CHILD_THREAD_ALIVE
147
148/* Check to see if the given thread is alive.
149
150 FIXME: Is kill() ever the right way to do this? I doubt it, but
151 for now we're going to try and be compatable with the old thread
152 code. */
153static int
154child_thread_alive (pid)
155 int pid;
156{
157 return (kill (pid, 0) != -1);
158}
159
160#endif
161
836e343b 162/* Attach to process PID, then initialize for debugging it. */
310cc570
RP
163
164static void
165child_attach (args, from_tty)
166 char *args;
167 int from_tty;
168{
310cc570
RP
169 if (!args)
170 error_no_arg ("process-id to attach");
171
172#ifndef ATTACH_DETACH
173 error ("Can't attach to a process on this machine.");
174#else
100f92e2
JK
175 {
176 char *exec_file;
177 int pid;
310cc570 178
100f92e2 179 pid = atoi (args);
310cc570 180
100f92e2
JK
181 if (pid == getpid()) /* Trying to masturbate? */
182 error ("I refuse to debug myself!");
310cc570 183
100f92e2
JK
184 if (from_tty)
185 {
186 exec_file = (char *) get_exec_file (0);
310cc570 187
100f92e2 188 if (exec_file)
67ac9759 189 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
100f92e2
JK
190 target_pid_to_str (pid));
191 else
67ac9759 192 printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
100f92e2 193
67ac9759 194 gdb_flush (gdb_stdout);
100f92e2 195 }
310cc570 196
100f92e2
JK
197 attach (pid);
198 inferior_pid = pid;
199 push_target (&child_ops);
200 }
310cc570
RP
201#endif /* ATTACH_DETACH */
202}
203
3aa6856a
JG
204
205/* Take a program previously attached to and detaches it.
206 The program resumes execution and will no longer stop
207 on signals, etc. We'd better not have left any breakpoints
208 in the program or it'll die when it hits one. For this
209 to work, it may be necessary for the process to have been
210 previously attached. It *might* work if the program was
211 started via the normal ptrace (PTRACE_TRACEME). */
bd5635a1
RP
212
213static void
214child_detach (args, from_tty)
215 char *args;
216 int from_tty;
217{
bd5635a1 218#ifdef ATTACH_DETACH
100f92e2
JK
219 {
220 int siggnal = 0;
221
222 if (from_tty)
223 {
224 char *exec_file = get_exec_file (0);
225 if (exec_file == 0)
226 exec_file = "";
67ac9759 227 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
100f92e2 228 target_pid_to_str (inferior_pid));
67ac9759 229 gdb_flush (gdb_stdout);
100f92e2
JK
230 }
231 if (args)
232 siggnal = atoi (args);
233
234 detach (siggnal);
235 inferior_pid = 0;
236 unpush_target (&child_ops);
237 }
bd5635a1 238#else
100f92e2 239 error ("This version of Unix does not support detaching a process.");
bd5635a1
RP
240#endif
241}
242
243/* Get ready to modify the registers array. On machines which store
244 individual registers, this doesn't need to do anything. On machines
245 which store all the registers in one fell swoop, this makes sure
246 that registers contains all the registers from the program being
247 debugged. */
248
dcc8abce 249static void
bd5635a1
RP
250child_prepare_to_store ()
251{
252#ifdef CHILD_PREPARE_TO_STORE
253 CHILD_PREPARE_TO_STORE ();
254#endif
255}
256
bd5635a1
RP
257/* Print status information about what we're accessing. */
258
259static void
dcc8abce
JG
260child_files_info (ignore)
261 struct target_ops *ignore;
bd5635a1 262{
67ac9759 263 printf_unfiltered ("\tUsing the running image of %s %s.\n",
de43d7d0 264 attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
bd5635a1
RP
265}
266
e1ce8aa5 267/* ARGSUSED */
70dcc196
JK
268static void
269child_open (arg, from_tty)
270 char *arg;
271 int from_tty;
272{
273 error ("Use the \"run\" command to start a Unix child process.");
274}
275
de43d7d0
SG
276/* Stub function which causes the inferior that runs it, to be ptrace-able
277 by its parent process. */
278
279static void
280ptrace_me ()
281{
282 /* "Trace me, Dr. Memory!" */
283 call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
284}
285
286/* Stub function which causes the GDB that runs it, to start ptrace-ing
287 the child process. */
288
4ef1f467 289static int
de43d7d0
SG
290ptrace_him (pid)
291 int pid;
292{
293 push_target (&child_ops);
67ac9759
JK
294
295#ifdef START_INFERIOR_TRAPS_EXPECTED
296 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
297#else
298 /* One trap to exec the shell, one to exec the program being debugged. */
299 startup_inferior (2);
300#endif
4ef1f467
DT
301
302 return pid;
de43d7d0
SG
303}
304
310cc570
RP
305/* Start an inferior Unix child process and sets inferior_pid to its pid.
306 EXEC_FILE is the file to run.
307 ALLARGS is a string containing the arguments to the program.
308 ENV is the environment vector to pass. Errors reported with error(). */
309
310cc570
RP
310static void
311child_create_inferior (exec_file, allargs, env)
312 char *exec_file;
313 char *allargs;
314 char **env;
315{
429f1c9f 316 fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL);
de43d7d0
SG
317 /* We are at the first instruction we care about. */
318 /* Pedal to the metal... */
67ac9759 319 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
310cc570
RP
320}
321
322static void
323child_mourn_inferior ()
324{
4ef1f467
DT
325 /* FIXME: Should be in a header file */
326 extern void proc_remove_foreign PARAMS ((int));
327
310cc570 328 unpush_target (&child_ops);
4ef1f467 329 proc_remove_foreign (inferior_pid);
310cc570
RP
330 generic_mourn_inferior ();
331}
332
333static int
334child_can_run ()
335{
4ef1f467
DT
336 /* This variable is controlled by modules that sit atop inftarg that may layer
337 their own process structure atop that provided here. hpux-thread.c does
338 this because of the Hpux user-mode level thread model. */
339
340 return !child_suppress_run;
341}
342
343/* Send a SIGINT to the process group. This acts just like the user typed a
344 ^C on the controlling terminal.
345
346 XXX - This may not be correct for all systems. Some may want to use
347 killpg() instead of kill (-pgrp). */
348
349static void
350child_stop ()
351{
352 extern pid_t inferior_process_group;
353
354 kill (-inferior_process_group, SIGINT);
310cc570 355}
3aa6856a 356\f
bd5635a1 357struct target_ops child_ops = {
dcc8abce
JG
358 "child", /* to_shortname */
359 "Unix child process", /* to_longname */
360 "Unix child process (started by the \"run\" command).", /* to_doc */
361 child_open, /* to_open */
362 0, /* to_close */
363 child_attach, /* to_attach */
4ef1f467
DT
364 NULL, /* to_post_attach */
365 NULL, /* to_require_attach */
dcc8abce 366 child_detach, /* to_detach */
4ef1f467 367 NULL, /* to_require_detach */
dcc8abce
JG
368 child_resume, /* to_resume */
369 child_wait, /* to_wait */
4ef1f467 370 NULL, /* to_post_wait */
dcc8abce
JG
371 fetch_inferior_registers, /* to_fetch_registers */
372 store_inferior_registers, /* to_store_registers */
373 child_prepare_to_store, /* to_prepare_to_store */
374 child_xfer_memory, /* to_xfer_memory */
375 child_files_info, /* to_files_info */
376 memory_insert_breakpoint, /* to_insert_breakpoint */
377 memory_remove_breakpoint, /* to_remove_breakpoint */
378 terminal_init_inferior, /* to_terminal_init */
379 terminal_inferior, /* to_terminal_inferior */
380 terminal_ours_for_output, /* to_terminal_ours_for_output */
381 terminal_ours, /* to_terminal_ours */
382 child_terminal_info, /* to_terminal_info */
383 kill_inferior, /* to_kill */
384 0, /* to_load */
385 0, /* to_lookup_symbol */
386 child_create_inferior, /* to_create_inferior */
4ef1f467
DT
387 NULL, /* to_post_startup_inferior */
388 NULL, /* to_acknowledge_created_inferior */
389 NULL, /* to_clone_and_follow_inferior */
390 NULL, /* to_post_follow_inferior_by_clone */
391 NULL, /* to_insert_fork_catchpoint */
392 NULL, /* to_remove_fork_catchpoint */
393 NULL, /* to_insert_vfork_catchpoint */
394 NULL, /* to_remove_vfork_catchpoint */
395 NULL, /* to_has_forked */
396 NULL, /* to_has_vforked */
397 NULL, /* to_can_follow_vfork_prior_to_exec */
398 NULL, /* to_post_follow_vfork */
399 NULL, /* to_insert_exec_catchpoint */
400 NULL, /* to_remove_exec_catchpoint */
401 NULL, /* to_has_execd */
402 NULL, /* to_reported_exec_events_per_exec_call */
403 NULL, /* to_has_syscall_event */
404 NULL, /* to_has_exited */
dcc8abce 405 child_mourn_inferior, /* to_mourn_inferior */
310cc570 406 child_can_run, /* to_can_run */
de43d7d0 407 0, /* to_notice_signals */
4ef1f467
DT
408 child_thread_alive, /* to_thread_alive */
409 child_stop, /* to_stop */
410 NULL, /* to_enable_exception_callback */
411 NULL, /* to_get_current_exception_event */
412 NULL, /* to_pid_to_exec_file */
413 NULL, /* to_core_file_to_sym_file */
dcc8abce
JG
414 process_stratum, /* to_stratum */
415 0, /* to_next */
416 1, /* to_has_all_memory */
417 1, /* to_has_memory */
418 1, /* to_has_stack */
419 1, /* to_has_registers */
420 1, /* to_has_execution */
4ef1f467
DT
421 0, /* to_sections */
422 0, /* to_sections_end */
dcc8abce 423 OPS_MAGIC /* to_magic */
bd5635a1
RP
424};
425
426void
427_initialize_inftarg ()
428{
4ef1f467
DT
429#ifdef HAVE_OPTIONAL_PROC_FS
430 char procname[32];
431 int fd;
432
433 /* If we have an optional /proc filesystem (e.g. under OSF/1),
434 don't add ptrace support if we can access the running GDB via /proc. */
435#ifndef PROC_NAME_FMT
436#define PROC_NAME_FMT "/proc/%05d"
437#endif
438 sprintf (procname, PROC_NAME_FMT, getpid ());
439 if ((fd = open (procname, O_RDONLY)) >= 0)
440 {
441 close (fd);
442 return;
443 }
444#endif
445
bd5635a1
RP
446 add_target (&child_ops);
447}
This page took 0.475863 seconds and 4 git commands to generate.