OSDN Git Service

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