import gdb-1999-12-21 snapshot
[external/binutils.git] / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2    Copyright 1990-1996, 1998, 1999 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5    ## Contains temporary hacks..
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23
24 #include "defs.h"
25 #include "frame.h"              /* required by inferior.h */
26 #include "inferior.h"
27 #include "target.h"
28 #include "gdbcore.h"
29 #include "command.h"
30 #include "gdb_stat.h"
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34
35 #ifdef HAVE_WAIT_H
36 #include <wait.h>
37 #else
38 #ifdef HAVE_SYS_WAIT_H
39 #include <sys/wait.h>
40 #endif
41 #endif
42
43 /* "wait.h" fills in the gaps left by <wait.h> */
44 #include "wait.h"
45
46 extern struct symtab_and_line *
47   child_enable_exception_callback PARAMS ((enum exception_event_kind, int));
48
49 extern struct exception_event_record *
50   child_get_current_exception_event PARAMS ((void));
51
52 extern void _initialize_inftarg PARAMS ((void));
53
54 static void
55 child_prepare_to_store PARAMS ((void));
56
57 #ifndef CHILD_WAIT
58 static int child_wait PARAMS ((int, struct target_waitstatus *));
59 #endif /* CHILD_WAIT */
60
61 #if !defined(CHILD_POST_WAIT)
62 void
63 child_post_wait PARAMS ((int, int));
64 #endif
65
66 static void child_open PARAMS ((char *, int));
67
68 static void
69 child_files_info PARAMS ((struct target_ops *));
70
71 static void
72 child_detach PARAMS ((char *, int));
73
74 static void
75 child_detach_from_process PARAMS ((int, char *, int, int));
76
77 static void
78 child_attach PARAMS ((char *, int));
79
80 static void
81 child_attach_to_process PARAMS ((char *, int, int));
82
83 #if !defined(CHILD_POST_ATTACH)
84 extern void child_post_attach PARAMS ((int));
85 #endif
86
87 static void
88 child_require_attach PARAMS ((char *, int));
89
90 static void
91 child_require_detach PARAMS ((int, char *, int));
92
93 static void
94 ptrace_me PARAMS ((void));
95
96 static void
97 ptrace_him PARAMS ((int));
98
99 static void
100 child_create_inferior PARAMS ((char *, char *, char **));
101
102 static void
103 child_mourn_inferior PARAMS ((void));
104
105 static int
106 child_can_run PARAMS ((void));
107
108 static void
109 child_stop PARAMS ((void));
110
111 #ifndef CHILD_THREAD_ALIVE
112 int child_thread_alive PARAMS ((int));
113 #endif
114
115 static void init_child_ops PARAMS ((void));
116
117 extern char **environ;
118
119 struct target_ops child_ops;
120
121 int child_suppress_run = 0;     /* Non-zero if inftarg should pretend not to
122                                    be a runnable target.  Used by targets
123                                    that can sit atop inftarg, such as HPUX
124                                    thread support.  */
125
126 #ifndef CHILD_WAIT
127
128 /*## */
129 /* Enable HACK for ttrace work.  In
130  * infttrace.c/require_notification_of_events,
131  * this is set to 0 so that the loop in child_wait
132  * won't loop.
133  */
134 int not_same_real_pid = 1;
135 /*## */
136
137
138 /* Wait for child to do something.  Return pid of child, or -1 in case
139    of error; store status through argument pointer OURSTATUS.  */
140
141 static int
142 child_wait (pid, ourstatus)
143      int pid;
144      struct target_waitstatus *ourstatus;
145 {
146   int save_errno;
147   int status;
148   char *execd_pathname = NULL;
149   int exit_status;
150   int related_pid;
151   int syscall_id;
152   enum target_waitkind kind;
153
154   do
155     {
156       set_sigint_trap ();       /* Causes SIGINT to be passed on to the
157                                    attached process. */
158       set_sigio_trap ();
159
160       pid = ptrace_wait (inferior_pid, &status);
161
162       save_errno = errno;
163
164       clear_sigio_trap ();
165
166       clear_sigint_trap ();
167
168       if (pid == -1)
169         {
170           if (save_errno == EINTR)
171             continue;
172
173           fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
174                               safe_strerror (save_errno));
175
176           /* Claim it exited with unknown signal.  */
177           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
178           ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
179           return -1;
180         }
181
182       /* Did it exit?
183        */
184       if (target_has_exited (pid, status, &exit_status))
185         {
186           /* ??rehrauer: For now, ignore this. */
187           continue;
188         }
189
190       if (!target_thread_alive (pid))
191         {
192           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
193           return pid;
194         }
195
196       if (target_has_forked (pid, &related_pid)
197           && ((pid == inferior_pid) || (related_pid == inferior_pid)))
198         {
199           ourstatus->kind = TARGET_WAITKIND_FORKED;
200           ourstatus->value.related_pid = related_pid;
201           return pid;
202         }
203
204       if (target_has_vforked (pid, &related_pid)
205           && ((pid == inferior_pid) || (related_pid == inferior_pid)))
206         {
207           ourstatus->kind = TARGET_WAITKIND_VFORKED;
208           ourstatus->value.related_pid = related_pid;
209           return pid;
210         }
211
212       if (target_has_execd (pid, &execd_pathname))
213         {
214           /* Are we ignoring initial exec events?  (This is likely because
215              we're in the process of starting up the inferior, and another
216              (older) mechanism handles those.)  If so, we'll report this
217              as a regular stop, not an exec.
218            */
219           if (inferior_ignoring_startup_exec_events)
220             {
221               inferior_ignoring_startup_exec_events--;
222             }
223           else
224             {
225               ourstatus->kind = TARGET_WAITKIND_EXECD;
226               ourstatus->value.execd_pathname = execd_pathname;
227               return pid;
228             }
229         }
230
231       /* All we must do with these is communicate their occurrence
232          to wait_for_inferior...
233        */
234       if (target_has_syscall_event (pid, &kind, &syscall_id))
235         {
236           ourstatus->kind = kind;
237           ourstatus->value.syscall_id = syscall_id;
238           return pid;
239         }
240
241       /*##  } while (pid != inferior_pid); ## *//* Some other child died or stopped */
242 /* hack for thread testing */
243     }
244   while ((pid != inferior_pid) && not_same_real_pid);
245 /*## */
246
247   store_waitstatus (ourstatus, status);
248   return pid;
249 }
250 #endif /* CHILD_WAIT */
251
252 #if !defined(CHILD_POST_WAIT)
253 void
254 child_post_wait (pid, wait_status)
255      int pid;
256      int wait_status;
257 {
258   /* This version of Unix doesn't require a meaningful "post wait"
259      operation.
260    */
261 }
262 #endif
263
264
265 #ifndef CHILD_THREAD_ALIVE
266
267 /* Check to see if the given thread is alive.
268
269    FIXME: Is kill() ever the right way to do this?  I doubt it, but
270    for now we're going to try and be compatable with the old thread
271    code.  */
272 int
273 child_thread_alive (pid)
274      int pid;
275 {
276   return (kill (pid, 0) != -1);
277 }
278
279 #endif
280
281 static void
282 child_attach_to_process (args, from_tty, after_fork)
283      char *args;
284      int from_tty;
285      int after_fork;
286 {
287   if (!args)
288     error_no_arg ("process-id to attach");
289
290 #ifndef ATTACH_DETACH
291   error ("Can't attach to a process on this machine.");
292 #else
293   {
294     char *exec_file;
295     int pid;
296     char *dummy;
297
298     dummy = args;
299     pid = strtol (args, &dummy, 0);
300     /* Some targets don't set errno on errors, grrr! */
301     if ((pid == 0) && (args == dummy))
302       error ("Illegal process-id: %s\n", args);
303
304     if (pid == getpid ())       /* Trying to masturbate? */
305       error ("I refuse to debug myself!");
306
307     if (from_tty)
308       {
309         exec_file = (char *) get_exec_file (0);
310
311         if (after_fork)
312           printf_unfiltered ("Attaching after fork to %s\n",
313                              target_pid_to_str (pid));
314         else if (exec_file)
315           printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
316                              target_pid_to_str (pid));
317         else
318           printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
319
320         gdb_flush (gdb_stdout);
321       }
322
323     if (!after_fork)
324       attach (pid);
325     else
326       REQUIRE_ATTACH (pid);
327
328     inferior_pid = pid;
329     push_target (&child_ops);
330   }
331 #endif /* ATTACH_DETACH */
332 }
333
334
335 /* Attach to process PID, then initialize for debugging it.  */
336
337 static void
338 child_attach (args, from_tty)
339      char *args;
340      int from_tty;
341 {
342   child_attach_to_process (args, from_tty, 0);
343 }
344
345 #if !defined(CHILD_POST_ATTACH)
346 void
347 child_post_attach (pid)
348      int pid;
349 {
350   /* This version of Unix doesn't require a meaningful "post attach"
351      operation by a debugger.  */
352 }
353 #endif
354
355 static void
356 child_require_attach (args, from_tty)
357      char *args;
358      int from_tty;
359 {
360   child_attach_to_process (args, from_tty, 1);
361 }
362
363 static void
364 child_detach_from_process (pid, args, from_tty, after_fork)
365      int pid;
366      char *args;
367      int from_tty;
368      int after_fork;
369 {
370 #ifdef ATTACH_DETACH
371   {
372     int siggnal = 0;
373
374     if (from_tty)
375       {
376         char *exec_file = get_exec_file (0);
377         if (exec_file == 0)
378           exec_file = "";
379         if (after_fork)
380           printf_unfiltered ("Detaching after fork from %s\n",
381                              target_pid_to_str (pid));
382         else
383           printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
384                              target_pid_to_str (pid));
385         gdb_flush (gdb_stdout);
386       }
387     if (args)
388       siggnal = atoi (args);
389
390     if (!after_fork)
391       detach (siggnal);
392     else
393       REQUIRE_DETACH (pid, siggnal);
394   }
395 #else
396   error ("This version of Unix does not support detaching a process.");
397 #endif
398 }
399
400 /* Take a program previously attached to and detaches it.
401    The program resumes execution and will no longer stop
402    on signals, etc.  We'd better not have left any breakpoints
403    in the program or it'll die when it hits one.  For this
404    to work, it may be necessary for the process to have been
405    previously attached.  It *might* work if the program was
406    started via the normal ptrace (PTRACE_TRACEME).  */
407
408 static void
409 child_detach (args, from_tty)
410      char *args;
411      int from_tty;
412 {
413   child_detach_from_process (inferior_pid, args, from_tty, 0);
414   inferior_pid = 0;
415   unpush_target (&child_ops);
416 }
417
418 static void
419 child_require_detach (pid, args, from_tty)
420      int pid;
421      char *args;
422      int from_tty;
423 {
424   child_detach_from_process (pid, args, from_tty, 1);
425 }
426
427
428 /* Get ready to modify the registers array.  On machines which store
429    individual registers, this doesn't need to do anything.  On machines
430    which store all the registers in one fell swoop, this makes sure
431    that registers contains all the registers from the program being
432    debugged.  */
433
434 static void
435 child_prepare_to_store ()
436 {
437 #ifdef CHILD_PREPARE_TO_STORE
438   CHILD_PREPARE_TO_STORE ();
439 #endif
440 }
441
442 /* Print status information about what we're accessing.  */
443
444 static void
445 child_files_info (ignore)
446      struct target_ops *ignore;
447 {
448   printf_unfiltered ("\tUsing the running image of %s %s.\n",
449       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
450 }
451
452 /* ARGSUSED */
453 static void
454 child_open (arg, from_tty)
455      char *arg;
456      int from_tty;
457 {
458   error ("Use the \"run\" command to start a Unix child process.");
459 }
460
461 /* Stub function which causes the inferior that runs it, to be ptrace-able
462    by its parent process.  */
463
464 static void
465 ptrace_me ()
466 {
467   /* "Trace me, Dr. Memory!" */
468   call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
469 }
470
471 /* Stub function which causes the GDB that runs it, to start ptrace-ing
472    the child process.  */
473
474 static void
475 ptrace_him (pid)
476      int pid;
477 {
478   push_target (&child_ops);
479
480   /* On some targets, there must be some explicit synchronization
481      between the parent and child processes after the debugger
482      forks, and before the child execs the debuggee program.  This
483      call basically gives permission for the child to exec.
484    */
485
486   target_acknowledge_created_inferior (pid);
487
488   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
489    * and will be 1 or 2 depending on whether we're starting
490    * without or with a shell.
491    */
492   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
493
494   /* On some targets, there must be some explicit actions taken after
495      the inferior has been started up.
496    */
497   target_post_startup_inferior (pid);
498 }
499
500 /* Start an inferior Unix child process and sets inferior_pid to its pid.
501    EXEC_FILE is the file to run.
502    ALLARGS is a string containing the arguments to the program.
503    ENV is the environment vector to pass.  Errors reported with error().  */
504
505 static void
506 child_create_inferior (exec_file, allargs, env)
507      char *exec_file;
508      char *allargs;
509      char **env;
510 {
511 #ifdef HPUXHPPA
512   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
513 #else
514   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
515 #endif
516   /* We are at the first instruction we care about.  */
517   /* Pedal to the metal... */
518   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
519 }
520
521 #if !defined(CHILD_POST_STARTUP_INFERIOR)
522 void
523 child_post_startup_inferior (pid)
524      int pid;
525 {
526   /* This version of Unix doesn't require a meaningful "post startup inferior"
527      operation by a debugger.
528    */
529 }
530 #endif
531
532 #if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
533 void
534 child_acknowledge_created_inferior (pid)
535      int pid;
536 {
537   /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
538      operation by a debugger.
539    */
540 }
541 #endif
542
543
544 void
545 child_clone_and_follow_inferior (child_pid, followed_child)
546      int child_pid;
547      int *followed_child;
548 {
549   clone_and_follow_inferior (child_pid, followed_child);
550
551   /* Don't resume CHILD_PID; it's stopped where it ought to be, until
552      the decision gets made elsewhere how to continue it.
553    */
554 }
555
556
557 #if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE)
558 void
559 child_post_follow_inferior_by_clone ()
560 {
561   /* This version of Unix doesn't require a meaningful "post follow inferior"
562      operation by a clone debugger.
563    */
564 }
565 #endif
566
567 #if !defined(CHILD_INSERT_FORK_CATCHPOINT)
568 int
569 child_insert_fork_catchpoint (pid)
570      int pid;
571 {
572   /* This version of Unix doesn't support notification of fork events.  */
573   return 0;
574 }
575 #endif
576
577 #if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
578 int
579 child_remove_fork_catchpoint (pid)
580      int pid;
581 {
582   /* This version of Unix doesn't support notification of fork events.  */
583   return 0;
584 }
585 #endif
586
587 #if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
588 int
589 child_insert_vfork_catchpoint (pid)
590      int pid;
591 {
592   /* This version of Unix doesn't support notification of vfork events.  */
593   return 0;
594 }
595 #endif
596
597 #if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
598 int
599 child_remove_vfork_catchpoint (pid)
600      int pid;
601 {
602   /* This version of Unix doesn't support notification of vfork events.  */
603   return 0;
604 }
605 #endif
606
607 #if !defined(CHILD_HAS_FORKED)
608 int
609 child_has_forked (pid, child_pid)
610      int pid;
611      int *child_pid;
612 {
613   /* This version of Unix doesn't support notification of fork events.  */
614   return 0;
615 }
616 #endif
617
618
619 #if !defined(CHILD_HAS_VFORKED)
620 int
621 child_has_vforked (pid, child_pid)
622      int pid;
623      int *child_pid;
624 {
625   /* This version of Unix doesn't support notification of vfork events.
626    */
627   return 0;
628 }
629 #endif
630
631
632 #if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
633 int
634 child_can_follow_vfork_prior_to_exec ()
635 {
636   /* This version of Unix doesn't support notification of vfork events.
637      However, if it did, it probably wouldn't allow vforks to be followed
638      before the following exec.
639    */
640   return 0;
641 }
642 #endif
643
644
645 #if !defined(CHILD_POST_FOLLOW_VFORK)
646 void
647 child_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child)
648      int parent_pid;
649      int followed_parent;
650      int child_pid;
651      int followed_child;
652 {
653   /* This version of Unix doesn't require a meaningful "post follow vfork"
654      operation by a clone debugger.
655    */
656 }
657 #endif
658
659 #if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
660 int
661 child_insert_exec_catchpoint (pid)
662      int pid;
663 {
664   /* This version of Unix doesn't support notification of exec events.  */
665   return 0;
666 }
667 #endif
668
669 #if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
670 int
671 child_remove_exec_catchpoint (pid)
672      int pid;
673 {
674   /* This version of Unix doesn't support notification of exec events.  */
675   return 0;
676 }
677 #endif
678
679 #if !defined(CHILD_HAS_EXECD)
680 int
681 child_has_execd (pid, execd_pathname)
682      int pid;
683      char **execd_pathname;
684 {
685   /* This version of Unix doesn't support notification of exec events.
686    */
687   return 0;
688 }
689 #endif
690
691
692 #if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
693 int
694 child_reported_exec_events_per_exec_call ()
695 {
696   /* This version of Unix doesn't support notification of exec events.
697    */
698   return 1;
699 }
700 #endif
701
702
703 #if !defined(CHILD_HAS_SYSCALL_EVENT)
704 int
705 child_has_syscall_event (pid, kind, syscall_id)
706      int pid;
707      enum target_waitkind *kind;
708      int *syscall_id;
709 {
710   /* This version of Unix doesn't support notification of syscall events.
711    */
712   return 0;
713 }
714 #endif
715
716
717 #if !defined(CHILD_HAS_EXITED)
718 int
719 child_has_exited (pid, wait_status, exit_status)
720      int pid;
721      int wait_status;
722      int *exit_status;
723 {
724   if (WIFEXITED (wait_status))
725     {
726       *exit_status = WEXITSTATUS (wait_status);
727       return 1;
728     }
729
730   if (WIFSIGNALED (wait_status))
731     {
732       *exit_status = 0;         /* ?? Don't know what else to say here. */
733       return 1;
734     }
735
736   /* ?? Do we really need to consult the event state, too?  Assume the
737      wait_state alone suffices.
738    */
739   return 0;
740 }
741 #endif
742
743
744 static void
745 child_mourn_inferior ()
746 {
747   unpush_target (&child_ops);
748   generic_mourn_inferior ();
749 }
750
751 static int
752 child_can_run ()
753 {
754   /* This variable is controlled by modules that sit atop inftarg that may layer
755      their own process structure atop that provided here.  hpux-thread.c does
756      this because of the Hpux user-mode level thread model.  */
757
758   return !child_suppress_run;
759 }
760
761 /* Send a SIGINT to the process group.  This acts just like the user typed a
762    ^C on the controlling terminal.
763
764    XXX - This may not be correct for all systems.  Some may want to use
765    killpg() instead of kill (-pgrp). */
766
767 static void
768 child_stop ()
769 {
770   extern pid_t inferior_process_group;
771
772   kill (-inferior_process_group, SIGINT);
773 }
774
775 #if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
776 struct symtab_and_line *
777 child_enable_exception_callback (kind, enable)
778      enum exception_event_kind kind;
779      int enable;
780 {
781   return (struct symtab_and_line *) NULL;
782 }
783 #endif
784
785 #if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
786 struct exception_event_record *
787 child_get_current_exception_event ()
788 {
789   return (struct exception_event_record *) NULL;
790 }
791 #endif
792
793
794 #if !defined(CHILD_PID_TO_EXEC_FILE)
795 char *
796 child_pid_to_exec_file (pid)
797      int pid;
798 {
799   /* This version of Unix doesn't support translation of a process ID
800      to the filename of the executable file.
801    */
802   return NULL;
803 }
804 #endif
805
806 char *
807 child_core_file_to_sym_file (core)
808      char *core;
809 {
810   /* The target stratum for a running executable need not support
811      this operation.
812    */
813   return NULL;
814 }
815 \f
816
817 #if !defined(CHILD_PID_TO_STR)
818 char *
819 child_pid_to_str (pid)
820      int pid;
821 {
822   return normal_pid_to_str (pid);
823 }
824 #endif
825
826 static void
827 init_child_ops ()
828 {
829   child_ops.to_shortname = "child";
830   child_ops.to_longname = "Unix child process";
831   child_ops.to_doc = "Unix child process (started by the \"run\" command).";
832   child_ops.to_open = child_open;
833   child_ops.to_attach = child_attach;
834   child_ops.to_post_attach = child_post_attach;
835   child_ops.to_require_attach = child_require_attach;
836   child_ops.to_detach = child_detach;
837   child_ops.to_require_detach = child_require_detach;
838   child_ops.to_resume = child_resume;
839   child_ops.to_wait = child_wait;
840   child_ops.to_post_wait = child_post_wait;
841   child_ops.to_fetch_registers = fetch_inferior_registers;
842   child_ops.to_store_registers = store_inferior_registers;
843   child_ops.to_prepare_to_store = child_prepare_to_store;
844   child_ops.to_xfer_memory = child_xfer_memory;
845   child_ops.to_files_info = child_files_info;
846   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
847   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
848   child_ops.to_terminal_init = terminal_init_inferior;
849   child_ops.to_terminal_inferior = terminal_inferior;
850   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
851   child_ops.to_terminal_ours = terminal_ours;
852   child_ops.to_terminal_info = child_terminal_info;
853   child_ops.to_kill = kill_inferior;
854   child_ops.to_create_inferior = child_create_inferior;
855   child_ops.to_post_startup_inferior = child_post_startup_inferior;
856   child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
857   child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
858   child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone;
859   child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
860   child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
861   child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
862   child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
863   child_ops.to_has_forked = child_has_forked;
864   child_ops.to_has_vforked = child_has_vforked;
865   child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec;
866   child_ops.to_post_follow_vfork = child_post_follow_vfork;
867   child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
868   child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
869   child_ops.to_has_execd = child_has_execd;
870   child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
871   child_ops.to_has_syscall_event = child_has_syscall_event;
872   child_ops.to_has_exited = child_has_exited;
873   child_ops.to_mourn_inferior = child_mourn_inferior;
874   child_ops.to_can_run = child_can_run;
875   child_ops.to_thread_alive = child_thread_alive;
876   child_ops.to_pid_to_str = child_pid_to_str;
877   child_ops.to_stop = child_stop;
878   child_ops.to_enable_exception_callback = child_enable_exception_callback;
879   child_ops.to_get_current_exception_event = child_get_current_exception_event;
880   child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
881   child_ops.to_core_file_to_sym_file = child_core_file_to_sym_file;
882   child_ops.to_stratum = process_stratum;
883   child_ops.to_has_all_memory = 1;
884   child_ops.to_has_memory = 1;
885   child_ops.to_has_stack = 1;
886   child_ops.to_has_registers = 1;
887   child_ops.to_has_execution = 1;
888   child_ops.to_magic = OPS_MAGIC;
889 }
890
891 void
892 _initialize_inftarg ()
893 {
894 #ifdef HAVE_OPTIONAL_PROC_FS
895   char procname[32];
896   int fd;
897
898   /* If we have an optional /proc filesystem (e.g. under OSF/1),
899      don't add ptrace support if we can access the running GDB via /proc.  */
900 #ifndef PROC_NAME_FMT
901 #define PROC_NAME_FMT "/proc/%05d"
902 #endif
903   sprintf (procname, PROC_NAME_FMT, getpid ());
904   if ((fd = open (procname, O_RDONLY)) >= 0)
905     {
906       close (fd);
907       return;
908     }
909 #endif
910
911   init_child_ops ();
912   add_target (&child_ops);
913 }