OSDN Git Service

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