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