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