hp merge changes -- too numerous to mention here; see ChangeLog and
[deliverable/binutils-gdb.git] / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
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 "gdbcore.h"
27 #include "command.h"
28 #include <signal.h>
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"
42
43 static void
44 child_prepare_to_store PARAMS ((void));
45
46 #ifndef CHILD_WAIT
47 static int child_wait PARAMS ((int, struct target_waitstatus *));
48 #endif /* CHILD_WAIT */
49
50 static void child_open PARAMS ((char *, int));
51
52 static void
53 child_files_info PARAMS ((struct target_ops *));
54
55 static void
56 child_detach PARAMS ((char *, int));
57
58 static void
59 child_attach PARAMS ((char *, int));
60
61 static void
62 ptrace_me PARAMS ((void));
63
64 static int
65 ptrace_him PARAMS ((int));
66
67 static void child_create_inferior PARAMS ((char *, char *, char **));
68
69 static void
70 child_mourn_inferior PARAMS ((void));
71
72 static int
73 child_can_run PARAMS ((void));
74
75 static int
76 proc_wait PARAMS ((int, int*));
77
78 static void
79 child_stop PARAMS ((void));
80
81 #ifndef CHILD_THREAD_ALIVE
82 static int child_thread_alive PARAMS ((int));
83 #endif
84
85 extern char **environ;
86
87 /* Forward declaration */
88 extern struct target_ops child_ops;
89
90 int 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. */
94 static int
95 proc_wait (pid, status)
96 int pid;
97 int *status;
98 {
99 #ifndef __GO32__
100 return wait (status);
101 #endif
102 }
103
104 #ifndef CHILD_WAIT
105
106 /* Wait for child to do something. Return pid of child, or -1 in case
107 of error; store status through argument pointer OURSTATUS. */
108
109 static int
110 child_wait (pid, ourstatus)
111 int pid;
112 struct target_waitstatus *ourstatus;
113 {
114 int save_errno;
115 int status;
116
117 do {
118 set_sigint_trap(); /* Causes SIGINT to be passed on to the
119 attached process. */
120 set_sigio_trap ();
121
122 pid = proc_wait (inferior_pid, &status);
123 save_errno = errno;
124
125 clear_sigio_trap ();
126
127 clear_sigint_trap();
128
129 if (pid == -1)
130 {
131 if (save_errno == EINTR)
132 continue;
133 fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
134 safe_strerror (save_errno));
135 /* Claim it exited with unknown signal. */
136 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
137 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
138 return -1;
139 }
140 } while (pid != inferior_pid); /* Some other child died or stopped */
141 store_waitstatus (ourstatus, status);
142 return pid;
143 }
144 #endif /* CHILD_WAIT */
145
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. */
153 static int
154 child_thread_alive (pid)
155 int pid;
156 {
157 return (kill (pid, 0) != -1);
158 }
159
160 #endif
161
162 /* Attach to process PID, then initialize for debugging it. */
163
164 static void
165 child_attach (args, from_tty)
166 char *args;
167 int from_tty;
168 {
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
175 {
176 char *exec_file;
177 int pid;
178
179 pid = atoi (args);
180
181 if (pid == getpid()) /* Trying to masturbate? */
182 error ("I refuse to debug myself!");
183
184 if (from_tty)
185 {
186 exec_file = (char *) get_exec_file (0);
187
188 if (exec_file)
189 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
190 target_pid_to_str (pid));
191 else
192 printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
193
194 gdb_flush (gdb_stdout);
195 }
196
197 attach (pid);
198 inferior_pid = pid;
199 push_target (&child_ops);
200 }
201 #endif /* ATTACH_DETACH */
202 }
203
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). */
212
213 static void
214 child_detach (args, from_tty)
215 char *args;
216 int from_tty;
217 {
218 #ifdef ATTACH_DETACH
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 = "";
227 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
228 target_pid_to_str (inferior_pid));
229 gdb_flush (gdb_stdout);
230 }
231 if (args)
232 siggnal = atoi (args);
233
234 detach (siggnal);
235 inferior_pid = 0;
236 unpush_target (&child_ops);
237 }
238 #else
239 error ("This version of Unix does not support detaching a process.");
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
249 static void
250 child_prepare_to_store ()
251 {
252 #ifdef CHILD_PREPARE_TO_STORE
253 CHILD_PREPARE_TO_STORE ();
254 #endif
255 }
256
257 /* Print status information about what we're accessing. */
258
259 static void
260 child_files_info (ignore)
261 struct target_ops *ignore;
262 {
263 printf_unfiltered ("\tUsing the running image of %s %s.\n",
264 attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
265 }
266
267 /* ARGSUSED */
268 static void
269 child_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
276 /* Stub function which causes the inferior that runs it, to be ptrace-able
277 by its parent process. */
278
279 static void
280 ptrace_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
289 static int
290 ptrace_him (pid)
291 int pid;
292 {
293 push_target (&child_ops);
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
301
302 return pid;
303 }
304
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
310 static void
311 child_create_inferior (exec_file, allargs, env)
312 char *exec_file;
313 char *allargs;
314 char **env;
315 {
316 fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL);
317 /* We are at the first instruction we care about. */
318 /* Pedal to the metal... */
319 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
320 }
321
322 static void
323 child_mourn_inferior ()
324 {
325 /* FIXME: Should be in a header file */
326 extern void proc_remove_foreign PARAMS ((int));
327
328 unpush_target (&child_ops);
329 proc_remove_foreign (inferior_pid);
330 generic_mourn_inferior ();
331 }
332
333 static int
334 child_can_run ()
335 {
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
349 static void
350 child_stop ()
351 {
352 extern pid_t inferior_process_group;
353
354 kill (-inferior_process_group, SIGINT);
355 }
356 \f
357 struct target_ops child_ops = {
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 */
364 NULL, /* to_post_attach */
365 NULL, /* to_require_attach */
366 child_detach, /* to_detach */
367 NULL, /* to_require_detach */
368 child_resume, /* to_resume */
369 child_wait, /* to_wait */
370 NULL, /* to_post_wait */
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 */
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 */
405 child_mourn_inferior, /* to_mourn_inferior */
406 child_can_run, /* to_can_run */
407 0, /* to_notice_signals */
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 */
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 */
421 0, /* to_sections */
422 0, /* to_sections_end */
423 OPS_MAGIC /* to_magic */
424 };
425
426 void
427 _initialize_inftarg ()
428 {
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
446 add_target (&child_ops);
447 }
This page took 0.038817 seconds and 5 git commands to generate.