This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[commit] Follow forks on HP-UX 10.20
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: gdb-patches at sourceware dot org
- Date: Tue, 26 Jul 2005 00:12:28 +0200 (CEST)
- Subject: [commit] Follow forks on HP-UX 10.20
Finally, the goal of this excercise. The code is also going to be
used on OpenBSD when I get the necessary kernel stuff committed. It
doesn't do follow-vfork yet. HP-UX 10.20 doesn't really allow you to
do anything with a vforked child until it execs. So follow-vfork
isn't useful until follow-exec is properly implemented.
Committed,
Mark
P.S. Daniel, I'm going to remove the messages from inf-ttrace.c such
that things behaves the same way on HP-UX 11.xx as they do on HP-UX
10.20.
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* inf-ptrace.c [PT_GET_PROCESS_STATE] (inf_ptrace_follow_fork):
New function.
(inf_ptrace_him, inf_ptrace_attach) [PT_GET_PROCESS_STATE]: Set
PTRACE_FORK event flag.
(inf_ptrace_wait) [PT_GET_PROCESS_STATE]: Handle PTRACE_FORK
event.
(inf_ptrace_target) [PT_GET_PROCESS_STATE]: Set to_follow_fork.
2005-07-25 Mark Kettenis <kettenis@gnu.org>
Index: inf-ptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ptrace.c,v
retrieving revision 1.22
diff -u -p -r1.22 inf-ptrace.c
--- inf-ptrace.c 25 Jul 2005 20:42:29 -0000 1.22
+++ inf-ptrace.c 25 Jul 2005 20:56:04 -0000
@@ -41,6 +41,59 @@
static struct target_ops *ptrace_ops_hack;
+#ifdef PT_GET_PROCESS_STATE
+
+static int
+inf_ptrace_follow_fork (int follow_child)
+{
+ pid_t pid, fpid;
+ ptrace_state_t pe;
+
+ /* FIXME: kettenis/20050720: This stuff should really be passed as
+ an argument by our caller. */
+ {
+ ptid_t ptid;
+ struct target_waitstatus status;
+
+ get_last_target_status (&ptid, &status);
+ gdb_assert (status.kind == TARGET_WAITKIND_FORKED);
+
+ pid = ptid_get_pid (ptid);
+ }
+
+ if (ptrace (PT_GET_PROCESS_STATE, pid,
+ (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+ perror_with_name (("ptrace"));
+
+ gdb_assert (pe.pe_report_event == PTRACE_FORK);
+ fpid = pe.pe_other_pid;
+
+ if (follow_child)
+ {
+ inferior_ptid = pid_to_ptid (fpid);
+ detach_breakpoints (pid);
+
+ /* Reset breakpoints in the child as appropriate. */
+ follow_inferior_reset_breakpoints ();
+
+ if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
+ perror_with_name (("ptrace"));
+ }
+ else
+ {
+ inferior_ptid = pid_to_ptid (pid);
+ detach_breakpoints (fpid);
+
+ if (ptrace (PT_DETACH, fpid, (PTRACE_TYPE_ARG3)1, 0) == -1)
+ perror_with_name (("ptrace"));
+ }
+
+ return 0;
+}
+
+#endif /* PT_GET_PROCESS_STATE */
+
+
/* Prepare to be traced. */
static void
@@ -55,6 +108,19 @@ inf_ptrace_me (void)
static void
inf_ptrace_him (int pid)
{
+#ifdef PT_GET_PROCESS_STATE
+ {
+ ptrace_event_t pe;
+
+ /* Set the initial event mask. */
+ memset (&pe, 0, sizeof pe);
+ pe.pe_set_event |= PTRACE_FORK;
+ if (ptrace (PT_SET_EVENT_MASK, pid,
+ (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+ perror_with_name (("ptrace"));
+ }
+#endif
+
push_target (ptrace_ops_hack);
/* On some targets, there must be some explicit synchronization
@@ -156,6 +222,19 @@ inf_ptrace_attach (char *args, int from_
error (_("This system does not support attaching to a process"));
#endif
+#ifdef PT_GET_PROCESS_STATE
+ {
+ ptrace_event_t pe;
+
+ /* Set the initial event mask. */
+ memset (&pe, 0, sizeof pe);
+ pe.pe_set_event |= PTRACE_FORK;
+ if (ptrace (PT_SET_EVENT_MASK, pid,
+ (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+ perror_with_name (("ptrace"));
+ }
+#endif
+
inferior_ptid = pid_to_ptid (pid);
push_target (ptrace_ops_hack);
@@ -310,6 +389,44 @@ inf_ptrace_wait (ptid_t ptid, struct tar
}
while (pid == -1);
+#ifdef PT_GET_PROCESS_STATE
+ if (WIFSTOPPED (status))
+ {
+ ptrace_state_t pe;
+ pid_t fpid;
+
+ if (ptrace (PT_GET_PROCESS_STATE, pid,
+ (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+ perror_with_name (("ptrace"));
+
+ switch (pe.pe_report_event)
+ {
+ case PTRACE_FORK:
+ ourstatus->kind = TARGET_WAITKIND_FORKED;
+ ourstatus->value.related_pid = pe.pe_other_pid;
+
+ /* Make sure the other end of the fork is stopped too. */
+ fpid = waitpid (pe.pe_other_pid, &status, 0);
+ if (fpid == -1)
+ perror_with_name (("waitpid"));
+
+ if (ptrace (PT_GET_PROCESS_STATE, fpid,
+ (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+ perror_with_name (("ptrace"));
+
+ gdb_assert (pe.pe_report_event == PTRACE_FORK);
+ gdb_assert (pe.pe_other_pid == pid);
+ if (fpid == ptid_get_pid (inferior_ptid))
+ {
+ ourstatus->value.related_pid = pe.pe_other_pid;
+ return pid_to_ptid (fpid);
+ }
+
+ return pid_to_ptid (pid);
+ }
+ }
+#endif
+
store_waitstatus (ourstatus, status);
return pid_to_ptid (pid);
}
@@ -471,6 +588,9 @@ inf_ptrace_target (void)
t->to_files_info = inf_ptrace_files_info;
t->to_kill = inf_ptrace_kill;
t->to_create_inferior = inf_ptrace_create_inferior;
+#ifdef PT_GET_PROCESS_STATE
+ t->to_follow_fork = inf_ptrace_follow_fork;
+#endif
t->to_mourn_inferior = inf_ptrace_mourn_inferior;
t->to_thread_alive = inf_ptrace_thread_alive;
t->to_pid_to_str = normal_pid_to_str;