* RFA: Actual support for tracing forks on GNU/Linux
@ 2003-06-18 23:29 Daniel Jacobowitz
2003-06-28 16:35 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2003-06-18 23:29 UTC (permalink / raw)
To: gdb-patches; +Cc: msnyder
This patch enables "catch fork" and "set follow-fork-mode child" for fork().
Other things from my working directory that doesn't include:
- vfork support - I'll do that separately once this in
- exec support - the code is still a mess
- exit event support - i.e. stopping the process just before it exits,
to take a look around - this confuses GDB very badly
- gdbserver support for any of the above
- enabling the testsuite checks for this - even worse of a mess
I hope to get at least native vfork support into GDB 6.0.
This patch works by adding a hook every time we attach to an LWP or fork a
new LWP, to set tracing flags on it. We enable event reporting for fork()
[which requires ~ 2.5.34 kernel; I heard that one of RH's backport kernels
included this, but I don't know if it still does.] Then, when we get a
fork, we end up attached to both parent and child. We remove breakpoints in
whichever one we don't care about, and then we detach it.
This both lets us choose which one to trace, and also fixes the problem
where breakpoints would be left in the inferior after it forked, causing the
child to die with SIGTRAP.
I had to override kill_inferior, for an issue discovered in testing: when
we're stopped with both processes attached, we have to make sure to kill
them both. We have to deal with this because the user could "catch fork",
and when they see the fork decide which one to debug.
I think that's everything. I'd like at least a nod from the threading
maintainers, since I had to hook into lin-lwp.c. OK?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
2003-06-18 Daniel Jacobowitz <drow@mvista.com>
* config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Define.
* config/nm-linux.h (linux_enable_event_reporting)
(linux_handle_extended_wait, linux_child_post_startup_inferior): New
prototypes.
(CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK)
(KILL_INFERIOR): Define.
* i386-linux-nat.c (child_post_startup_inferior): New function.
* i386-nat.c (child_post_startup_inferior): Wrap in #ifdef.
* infptrace.c (kill_inferior): Wrap in #ifdef.
* lin-lwp.c (lin_lwp_attach_lwp): Call child_post_attach after
attaching to each LWP.
(child_wait, lin_lwp_wait): Call linux_handle_extended_wait.
(init_lin_lwp_ops): Fill in some more operations.
* linux-nat.c (linux_enable_event_reporting): New function.
(child_post_attach, linux_child_post_startup_inferior)
(child_post_startup_inferior, child_follow_fork)
(linux_handle_extended_wait, kill_inferior): New functions.
diff -Nurp -x '*.gmo' src-one/gdb/config/i386/nm-linux.h src-two/gdb/config/i386/nm-linux.h
--- src-one/gdb/config/i386/nm-linux.h 2002-11-09 16:31:12.000000000 -0500
+++ src-two/gdb/config/i386/nm-linux.h 2003-06-18 17:54:59.000000000 -0400
@@ -82,4 +82,9 @@ extern int cannot_store_register (int re
/* Override child_resume in `infptrace.c'. */
#define CHILD_RESUME
+/* `linux-nat.c' and `i386-nat.c' have their own versions of
+ child_post_startup_inferior. Define this to use the copy in
+ `i386-linux-nat.c' instead, which calls both. */
+#define LINUX_CHILD_POST_STARTUP_INFERIOR
+
#endif /* nm-linux.h */
diff -Nurp -x '*.gmo' src-one/gdb/config/nm-linux.h src-two/gdb/config/nm-linux.h
--- src-one/gdb/config/nm-linux.h 2003-06-18 18:27:58.000000000 -0400
+++ src-two/gdb/config/nm-linux.h 2003-06-18 18:10:47.000000000 -0400
@@ -79,7 +79,15 @@ extern int linux_proc_xfer_memory (CORE_
struct target_ops *target);
extern void linux_record_stopped_pid (int pid);
+extern void linux_enable_event_reporting (ptid_t ptid);
+extern ptid_t linux_handle_extended_wait (int pid, int status,
+ struct target_waitstatus *ourstatus);
+extern void linux_child_post_startup_inferior (ptid_t ptid);
#define CHILD_INSERT_FORK_CATCHPOINT
#define CHILD_INSERT_VFORK_CATCHPOINT
#define CHILD_INSERT_EXEC_CATCHPOINT
+#define CHILD_POST_STARTUP_INFERIOR
+#define CHILD_POST_ATTACH
+#define CHILD_FOLLOW_FORK
+#define KILL_INFERIOR
diff -Nurp -x '*.gmo' src-one/gdb/i386-linux-nat.c src-two/gdb/i386-linux-nat.c
--- src-one/gdb/i386-linux-nat.c 2003-06-04 16:51:29.000000000 -0400
+++ src-two/gdb/i386-linux-nat.c 2003-06-18 17:16:59.000000000 -0400
@@ -890,6 +890,13 @@ child_resume (ptid_t ptid, int step, enu
if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
perror_with_name ("ptrace");
}
+
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+ i386_cleanup_dregs ();
+ linux_child_post_startup_inferior (ptid);
+}
\f
/* Register that we are able to handle GNU/Linux ELF core file
diff -Nurp -x '*.gmo' src-one/gdb/i386-nat.c src-two/gdb/i386-nat.c
--- src-one/gdb/i386-nat.c 2002-07-04 08:32:28.000000000 -0400
+++ src-two/gdb/i386-nat.c 2003-06-18 17:17:40.000000000 -0400
@@ -230,6 +230,7 @@ i386_cleanup_dregs (void)
dr_status_mirror = 0;
}
+#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR
/* Reset all debug registers at each new startup
to avoid missing watchpoints after restart. */
void
@@ -237,6 +238,7 @@ child_post_startup_inferior (ptid_t ptid
{
i386_cleanup_dregs ();
}
+#endif /* LINUX_CHILD_POST_STARTUP_INFERIOR */
/* Print the values of the mirrored debug registers.
This is called when maint_show_dr is non-zero. To set that
diff -Nurp -x '*.gmo' src-one/gdb/infptrace.c src-two/gdb/infptrace.c
--- src-one/gdb/infptrace.c 2003-06-18 17:18:44.000000000 -0400
+++ src-two/gdb/infptrace.c 2003-06-18 17:19:07.000000000 -0400
@@ -208,6 +208,7 @@ ptrace_wait (ptid_t ptid, int *status)
return wstate;
}
+#ifndef KILL_INFERIOR
void
kill_inferior (void)
{
@@ -229,6 +230,7 @@ kill_inferior (void)
ptrace_wait (null_ptid, &status);
target_mourn_inferior ();
}
+#endif /* KILL_INFERIOR */
#ifndef CHILD_RESUME
diff -Nurp -x '*.gmo' src-one/gdb/lin-lwp.c src-two/gdb/lin-lwp.c
--- src-one/gdb/lin-lwp.c 2003-06-18 18:27:58.000000000 -0400
+++ src-two/gdb/lin-lwp.c 2003-06-18 17:48:29.000000000 -0400
@@ -399,6 +399,8 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver
gdb_assert (pid == GET_LWP (ptid)
&& WIFSTOPPED (status) && WSTOPSIG (status));
+ child_post_attach (pid);
+
lp->stopped = 1;
if (debug_lin_lwp)
@@ -1142,6 +1144,10 @@ child_wait (ptid_t ptid, struct target_w
return minus_one_ptid;
}
+ /* Handle GNU/Linux's extended waitstatus for trace events. */
+ if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
+ return linux_handle_extended_wait (pid, status, ourstatus);
+
store_waitstatus (ourstatus, status);
return pid_to_ptid (pid);
}
@@ -1563,6 +1569,14 @@ retry:
else
trap_ptid = null_ptid;
+ /* Handle GNU/Linux's extended waitstatus for trace events. */
+ if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
+ {
+ linux_handle_extended_wait (ptid_get_pid (trap_ptid),
+ status, ourstatus);
+ return trap_ptid;
+ }
+
store_waitstatus (ourstatus, status);
return (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid)));
}
@@ -1732,6 +1746,12 @@ init_lin_lwp_ops (void)
lin_lwp_ops.to_mourn_inferior = lin_lwp_mourn_inferior;
lin_lwp_ops.to_thread_alive = lin_lwp_thread_alive;
lin_lwp_ops.to_pid_to_str = lin_lwp_pid_to_str;
+ lin_lwp_ops.to_post_startup_inferior = child_post_startup_inferior;
+ lin_lwp_ops.to_post_attach = child_post_attach;
+ lin_lwp_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
+ lin_lwp_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
+ lin_lwp_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
+
lin_lwp_ops.to_stratum = thread_stratum;
lin_lwp_ops.to_has_thread_control = tc_schedlock;
lin_lwp_ops.to_magic = OPS_MAGIC;
diff -Nurp -x '*.gmo' src-one/gdb/linux-nat.c src-two/gdb/linux-nat.c
--- src-one/gdb/linux-nat.c 2003-06-18 18:27:58.000000000 -0400
+++ src-two/gdb/linux-nat.c 2003-06-18 18:30:10.000000000 -0400
@@ -54,6 +54,8 @@
#define __WALL 0x40000000 /* Wait for any child. */
#endif
+extern struct target_ops child_ops;
+
struct simple_pid_list
{
int pid;
@@ -187,13 +189,147 @@ linux_supports_tracefork (void)
}
\f
+void
+linux_enable_event_reporting (ptid_t ptid)
+{
+ int pid = ptid_get_pid (ptid);
+ int options;
+
+ if (! linux_supports_tracefork ())
+ return;
+
+ options = PTRACE_O_TRACEFORK;
+
+ ptrace (PTRACE_SETOPTIONS, pid, 0, options);
+}
+
+void
+child_post_attach (int pid)
+{
+ linux_enable_event_reporting (pid_to_ptid (pid));
+}
+
+void
+linux_child_post_startup_inferior (ptid_t ptid)
+{
+ linux_enable_event_reporting (ptid);
+}
+
+#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR
+void
+child_post_startup_inferior (ptid_t ptid)
+{
+ linux_child_post_startup_inferior (ptid);
+}
+#endif
+
int
-child_insert_fork_catchpoint (int pid)
+child_follow_fork (int follow_child)
{
- if (linux_supports_tracefork ())
- error ("Fork catchpoints have not been implemented yet.");
+ ptid_t last_ptid;
+ struct target_waitstatus last_status;
+ int parent_pid, child_pid;
+
+ get_last_target_status (&last_ptid, &last_status);
+ parent_pid = ptid_get_pid (last_ptid);
+ child_pid = last_status.value.related_pid;
+
+ if (! follow_child)
+ {
+ /* We're already attached to the parent, by default. */
+
+ /* Before detaching from the child, remove all breakpoints from
+ it. (This won't actually modify the breakpoint list, but will
+ physically remove the breakpoints from the child.) */
+ detach_breakpoints (child_pid);
+
+ fprintf_filtered (gdb_stdout,
+ "Detaching after fork from child process %d.\n",
+ child_pid);
+
+ ptrace (PTRACE_DETACH, child_pid, 0, 0);
+ }
else
+ {
+ char child_pid_spelling[40];
+
+ /* Needed to keep the breakpoint lists in sync. */
+ detach_breakpoints (child_pid);
+
+ /* Before detaching from the parent, remove all breakpoints from it. */
+ remove_breakpoints ();
+
+ fprintf_filtered (gdb_stdout,
+ "Attaching after fork to child process %d.\n",
+ child_pid);
+
+ target_detach (NULL, 0);
+
+ inferior_ptid = pid_to_ptid (child_pid);
+ push_target (&child_ops);
+
+ /* Reset breakpoints in the child as appropriate. */
+ follow_inferior_reset_breakpoints ();
+ }
+
+ return 0;
+}
+
+ptid_t
+linux_handle_extended_wait (int pid, int status,
+ struct target_waitstatus *ourstatus)
+{
+ int event = status >> 16;
+
+ if (event == PTRACE_EVENT_CLONE)
+ internal_error (__FILE__, __LINE__,
+ "unexpected clone event");
+
+ if (event == PTRACE_EVENT_FORK)
+ {
+ unsigned long new_pid;
+ int ret;
+
+ ptrace (PTRACE_GETEVENTMSG, pid, 0, &new_pid);
+
+ /* If we haven't already seen the new PID stop, wait for it now. */
+ if (! pull_pid_from_list (&stopped_pids, new_pid))
+ {
+ /* The new child has a pending SIGSTOP. We can't affect it until it
+ hits the SIGSTOP, but we're already attached.
+
+ It won't be a clone (we didn't ask for clones in the event mask)
+ so we can just call waitpid and wait for the SIGSTOP. */
+ do {
+ ret = waitpid (new_pid, &status, 0);
+ } while (ret == -1 && errno == EINTR);
+ if (ret == -1)
+ perror_with_name ("waiting for new child");
+ else if (ret != new_pid)
+ internal_error (__FILE__, __LINE__,
+ "wait returned unexpected PID %d", ret);
+ else if (!WIFSTOPPED (status) || WSTOPSIG (status) != SIGSTOP)
+ internal_error (__FILE__, __LINE__,
+ "wait returned unexpected status 0x%x", status);
+ }
+
+ ourstatus->kind = TARGET_WAITKIND_FORKED;
+ ourstatus->value.related_pid = new_pid;
+ return inferior_ptid;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "unknown ptrace event %d", event);
+}
+
+\f
+int
+child_insert_fork_catchpoint (int pid)
+{
+ if (! linux_supports_tracefork ())
error ("Your system does not support fork catchpoints.");
+
+ return 0;
}
int
@@ -214,4 +350,43 @@ child_insert_exec_catchpoint (int pid)
error ("Your system does not support exec catchpoints.");
}
+void
+kill_inferior (void)
+{
+ int status;
+ int pid = PIDGET (inferior_ptid);
+ struct target_waitstatus last;
+ ptid_t last_ptid;
+ int ret;
+
+ if (pid == 0)
+ return;
+
+ /* If we're stopped while forking and we haven't followed yet, kill the
+ other task. We need to do this first because the parent will be
+ sleeping if this is a vfork. */
+
+ get_last_target_status (&last_ptid, &last);
+ if (last.kind == TARGET_WAITKIND_FORKED
+ || last.kind == TARGET_WAITKIND_VFORKED)
+ {
+ ptrace (PT_KILL, last.value.related_pid);
+ ptrace_wait (null_ptid, &status);
+ }
+
+ /* Kill the current process. */
+ ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0);
+ ret = ptrace_wait (null_ptid, &status);
+
+ /* We might get a SIGCHLD instead of an exit status. This is
+ aggravated by the first kill above - a child has just died. */
+
+ while (ret == pid && WIFSTOPPED (status))
+ {
+ ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0);
+ ret = ptrace_wait (null_ptid, &status);
+ }
+
+ target_mourn_inferior ();
+}
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-06-18 23:29 RFA: Actual support for tracing forks on GNU/Linux Daniel Jacobowitz @ 2003-06-28 16:35 ` Daniel Jacobowitz 2003-07-09 21:57 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2003-06-28 16:35 UTC (permalink / raw) To: gdb-patches, msnyder On Wed, Jun 18, 2003 at 07:29:42PM -0400, Daniel Jacobowitz wrote: > This patch enables "catch fork" and "set follow-fork-mode child" for fork(). > > Other things from my working directory that doesn't include: > - vfork support - I'll do that separately once this in > - exec support - the code is still a mess > - exit event support - i.e. stopping the process just before it exits, > to take a look around - this confuses GDB very badly > - gdbserver support for any of the above > - enabling the testsuite checks for this - even worse of a mess > I hope to get at least native vfork support into GDB 6.0. > > This patch works by adding a hook every time we attach to an LWP or fork a > new LWP, to set tracing flags on it. We enable event reporting for fork() > [which requires ~ 2.5.34 kernel; I heard that one of RH's backport kernels > included this, but I don't know if it still does.] Then, when we get a > fork, we end up attached to both parent and child. We remove breakpoints in > whichever one we don't care about, and then we detach it. > > This both lets us choose which one to trace, and also fixes the problem > where breakpoints would be left in the inferior after it forked, causing the > child to die with SIGTRAP. > > I had to override kill_inferior, for an issue discovered in testing: when > we're stopped with both processes attached, we have to make sure to kill > them both. We have to deal with this because the user could "catch fork", > and when they see the fork decide which one to debug. > > I think that's everything. I'd like at least a nod from the threading > maintainers, since I had to hook into lin-lwp.c. OK? Ping? > 2003-06-18 Daniel Jacobowitz <drow@mvista.com> > > * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Define. > * config/nm-linux.h (linux_enable_event_reporting) > (linux_handle_extended_wait, linux_child_post_startup_inferior): New > prototypes. > (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) > (KILL_INFERIOR): Define. > * i386-linux-nat.c (child_post_startup_inferior): New function. > * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. > * infptrace.c (kill_inferior): Wrap in #ifdef. > * lin-lwp.c (lin_lwp_attach_lwp): Call child_post_attach after > attaching to each LWP. > (child_wait, lin_lwp_wait): Call linux_handle_extended_wait. > (init_lin_lwp_ops): Fill in some more operations. > * linux-nat.c (linux_enable_event_reporting): New function. > (child_post_attach, linux_child_post_startup_inferior) > (child_post_startup_inferior, child_follow_fork) > (linux_handle_extended_wait, kill_inferior): New functions. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-06-28 16:35 ` Daniel Jacobowitz @ 2003-07-09 21:57 ` Daniel Jacobowitz 2003-07-24 18:48 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2003-07-09 21:57 UTC (permalink / raw) To: gdb-patches, msnyder, kettenis On Sat, Jun 28, 2003 at 12:34:44PM -0400, Daniel Jacobowitz wrote: > On Wed, Jun 18, 2003 at 07:29:42PM -0400, Daniel Jacobowitz wrote: > > This patch enables "catch fork" and "set follow-fork-mode child" for fork(). > > > > Other things from my working directory that doesn't include: > > - vfork support - I'll do that separately once this in > > - exec support - the code is still a mess > > - exit event support - i.e. stopping the process just before it exits, > > to take a look around - this confuses GDB very badly > > - gdbserver support for any of the above > > - enabling the testsuite checks for this - even worse of a mess > > I hope to get at least native vfork support into GDB 6.0. > > > > This patch works by adding a hook every time we attach to an LWP or fork a > > new LWP, to set tracing flags on it. We enable event reporting for fork() > > [which requires ~ 2.5.34 kernel; I heard that one of RH's backport kernels > > included this, but I don't know if it still does.] Then, when we get a > > fork, we end up attached to both parent and child. We remove breakpoints in > > whichever one we don't care about, and then we detach it. > > > > This both lets us choose which one to trace, and also fixes the problem > > where breakpoints would be left in the inferior after it forked, causing the > > child to die with SIGTRAP. > > > > I had to override kill_inferior, for an issue discovered in testing: when > > we're stopped with both processes attached, we have to make sure to kill > > them both. We have to deal with this because the user could "catch fork", > > and when they see the fork decide which one to debug. > > > > I think that's everything. I'd like at least a nod from the threading > > maintainers, since I had to hook into lin-lwp.c. OK? Ping? If neither of our thread maintainers feels comfortable commenting on this patch I'm willing to approve it myself, but I'd prefer a comment from the maintainers of lin-lwp. > > 2003-06-18 Daniel Jacobowitz <drow@mvista.com> > > > > * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Define. > > * config/nm-linux.h (linux_enable_event_reporting) > > (linux_handle_extended_wait, linux_child_post_startup_inferior): New > > prototypes. > > (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) > > (KILL_INFERIOR): Define. > > * i386-linux-nat.c (child_post_startup_inferior): New function. > > * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. > > * infptrace.c (kill_inferior): Wrap in #ifdef. > > * lin-lwp.c (lin_lwp_attach_lwp): Call child_post_attach after > > attaching to each LWP. > > (child_wait, lin_lwp_wait): Call linux_handle_extended_wait. > > (init_lin_lwp_ops): Fill in some more operations. > > * linux-nat.c (linux_enable_event_reporting): New function. > > (child_post_attach, linux_child_post_startup_inferior) > > (child_post_startup_inferior, child_follow_fork) > > (linux_handle_extended_wait, kill_inferior): New functions. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-07-09 21:57 ` Daniel Jacobowitz @ 2003-07-24 18:48 ` Daniel Jacobowitz 2003-08-10 16:11 ` Mark Kettenis 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2003-07-24 18:48 UTC (permalink / raw) To: gdb-patches, msnyder, kettenis On Wed, Jul 09, 2003 at 05:57:13PM -0400, Daniel Jacobowitz wrote: > On Sat, Jun 28, 2003 at 12:34:44PM -0400, Daniel Jacobowitz wrote: > > On Wed, Jun 18, 2003 at 07:29:42PM -0400, Daniel Jacobowitz wrote: > > > This patch enables "catch fork" and "set follow-fork-mode child" for fork(). > > > > > > Other things from my working directory that doesn't include: > > > - vfork support - I'll do that separately once this in > > > - exec support - the code is still a mess > > > - exit event support - i.e. stopping the process just before it exits, > > > to take a look around - this confuses GDB very badly > > > - gdbserver support for any of the above > > > - enabling the testsuite checks for this - even worse of a mess > > > I hope to get at least native vfork support into GDB 6.0. > > > > > > This patch works by adding a hook every time we attach to an LWP or fork a > > > new LWP, to set tracing flags on it. We enable event reporting for fork() > > > [which requires ~ 2.5.34 kernel; I heard that one of RH's backport kernels > > > included this, but I don't know if it still does.] Then, when we get a > > > fork, we end up attached to both parent and child. We remove breakpoints in > > > whichever one we don't care about, and then we detach it. > > > > > > This both lets us choose which one to trace, and also fixes the problem > > > where breakpoints would be left in the inferior after it forked, causing the > > > child to die with SIGTRAP. > > > > > > I had to override kill_inferior, for an issue discovered in testing: when > > > we're stopped with both processes attached, we have to make sure to kill > > > them both. We have to deal with this because the user could "catch fork", > > > and when they see the fork decide which one to debug. > > > > > > I think that's everything. I'd like at least a nod from the threading > > > maintainers, since I had to hook into lin-lwp.c. OK? > > Ping? If neither of our thread maintainers feels comfortable > commenting on this patch I'm willing to approve it myself, but I'd > prefer a comment from the maintainers of lin-lwp. Ping. > > > 2003-06-18 Daniel Jacobowitz <drow@mvista.com> > > > > > > * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Define. > > > * config/nm-linux.h (linux_enable_event_reporting) > > > (linux_handle_extended_wait, linux_child_post_startup_inferior): New > > > prototypes. > > > (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK) > > > (KILL_INFERIOR): Define. > > > * i386-linux-nat.c (child_post_startup_inferior): New function. > > > * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. > > > * infptrace.c (kill_inferior): Wrap in #ifdef. > > > * lin-lwp.c (lin_lwp_attach_lwp): Call child_post_attach after > > > attaching to each LWP. > > > (child_wait, lin_lwp_wait): Call linux_handle_extended_wait. > > > (init_lin_lwp_ops): Fill in some more operations. > > > * linux-nat.c (linux_enable_event_reporting): New function. > > > (child_post_attach, linux_child_post_startup_inferior) > > > (child_post_startup_inferior, child_follow_fork) > > > (linux_handle_extended_wait, kill_inferior): New functions. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-07-24 18:48 ` Daniel Jacobowitz @ 2003-08-10 16:11 ` Mark Kettenis 2003-08-17 18:22 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Mark Kettenis @ 2003-08-10 16:11 UTC (permalink / raw) To: drow; +Cc: gdb-patches, msnyder Date: Thu, 24 Jul 2003 14:48:49 -0400 From: Daniel Jacobowitz <drow@mvista.com> Ping. Sorry Daniel for not responding earlier. I've had almost no time to spend on hacking since the second half of june and I've just returned from a vacation in Finland. Anyway, I do have a few comments: * I'm not very enthousiastic about the staggering of CHILD_POST_STARTUP_INFERIOR and LINUX_CHILD_POST_STARTUP_INFERIOR, especially since it infects i386-nat.c. However, I'm pretty sure there isn't a better alternative that doesn't involve redisigning the target vector :-(. I'd appreciate though if you could stick in a comment somewhere that says this is really ugly. * The changes to lin-lwp.c seem pretty much OK to me. So I think this can go in. Mark ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-08-10 16:11 ` Mark Kettenis @ 2003-08-17 18:22 ` Daniel Jacobowitz 2003-08-18 9:09 ` Michal Ludvig 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2003-08-17 18:22 UTC (permalink / raw) To: gdb-patches On Sun, Aug 10, 2003 at 06:11:41PM +0200, Mark Kettenis wrote: > Date: Thu, 24 Jul 2003 14:48:49 -0400 > From: Daniel Jacobowitz <drow@mvista.com> > > Ping. > > Sorry Daniel for not responding earlier. I've had almost no time to > spend on hacking since the second half of june and I've just returned > from a vacation in Finland. Anyway, I do have a few comments: > > * I'm not very enthousiastic about the staggering of > CHILD_POST_STARTUP_INFERIOR and LINUX_CHILD_POST_STARTUP_INFERIOR, > especially since it infects i386-nat.c. However, I'm pretty sure > there isn't a better alternative that doesn't involve redisigning > the target vector :-(. I'd appreciate though if you could stick in > a comment somewhere that says this is really ugly. > > * The changes to lin-lwp.c seem pretty much OK to me. > > So I think this can go in. Thanks. I agree with your reaction to CHILD_POST_STARTUP_INFERIOR, so I've clarified the comment. Also needed to move a few prototypes to linux-nat.h. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer 2003-08-17 Daniel Jacobowitz <drow@mvista.com> * Makefile.in (i386-linux-nat.o): Update dependencies. * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): Define. * config/nm-linux.h (CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH) (CHILD_FOLLOW_FORK, KILL_INFERIOR): Define. * i386-linux-nat.c: Include "linux-nat.h". (child_post_startup_inferior): New function. * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. * infptrace.c (kill_inferior): Wrap in #ifdef. * lin-lwp.c (lin_lwp_attach_lwp): Call child_post_attach after attaching to each LWP. (child_wait, lin_lwp_wait): Call linux_handle_extended_wait. (init_lin_lwp_ops): Fill in some more operations. * linux-nat.h (linux_enable_event_reporting) (linux_handle_extended_wait, linux_child_post_startup_inferior): New prototypes. * linux-nat.c (linux_enable_event_reporting): New function. (child_post_attach, linux_child_post_startup_inferior) (child_post_startup_inferior, child_follow_fork) (linux_handle_extended_wait, kill_inferior): New functions. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.429 diff -u -p -r1.429 Makefile.in --- Makefile.in 16 Aug 2003 17:49:12 -0000 1.429 +++ Makefile.in 17 Aug 2003 17:46:09 -0000 @@ -1843,7 +1843,7 @@ i386-interix-tdep.o: i386-interix-tdep.c i386-linux-nat.o: i386-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \ $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(gregset_h) \ $(i387_tdep_h) $(i386_tdep_h) $(i386_linux_tdep_h) \ - $(gdb_proc_service_h) + $(gdb_proc_service_h) $(linux_nat_h) i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \ $(value_h) $(regcache_h) $(inferior_h) $(reggroups_h) $(symtab_h) \ $(symfile_h) $(objfiles_h) $(solib_svr4_h) $(osabi_h) $(i386_tdep_h) \ Index: i386-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386-linux-nat.c,v retrieving revision 1.47 diff -u -p -r1.47 i386-linux-nat.c --- i386-linux-nat.c 4 Jun 2003 20:51:29 -0000 1.47 +++ i386-linux-nat.c 17 Aug 2003 17:46:10 -0000 @@ -23,6 +23,7 @@ #include "inferior.h" #include "gdbcore.h" #include "regcache.h" +#include "linux-nat.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -889,6 +890,13 @@ child_resume (ptid_t ptid, int step, enu if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1) perror_with_name ("ptrace"); +} + +void +child_post_startup_inferior (ptid_t ptid) +{ + i386_cleanup_dregs (); + linux_child_post_startup_inferior (ptid); } \f Index: i386-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386-nat.c,v retrieving revision 1.5 diff -u -p -r1.5 i386-nat.c --- i386-nat.c 4 Jul 2002 12:32:28 -0000 1.5 +++ i386-nat.c 17 Aug 2003 17:46:10 -0000 @@ -230,6 +230,7 @@ i386_cleanup_dregs (void) dr_status_mirror = 0; } +#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR /* Reset all debug registers at each new startup to avoid missing watchpoints after restart. */ void @@ -237,6 +238,7 @@ child_post_startup_inferior (ptid_t ptid { i386_cleanup_dregs (); } +#endif /* LINUX_CHILD_POST_STARTUP_INFERIOR */ /* Print the values of the mirrored debug registers. This is called when maint_show_dr is non-zero. To set that Index: infptrace.c =================================================================== RCS file: /cvs/src/src/gdb/infptrace.c,v retrieving revision 1.26 diff -u -p -r1.26 infptrace.c --- infptrace.c 22 May 2003 15:46:20 -0000 1.26 +++ infptrace.c 17 Aug 2003 17:46:10 -0000 @@ -208,6 +208,7 @@ ptrace_wait (ptid_t ptid, int *status) return wstate; } +#ifndef KILL_INFERIOR void kill_inferior (void) { @@ -229,6 +230,7 @@ kill_inferior (void) ptrace_wait (null_ptid, &status); target_mourn_inferior (); } +#endif /* KILL_INFERIOR */ #ifndef CHILD_RESUME Index: lin-lwp.c =================================================================== RCS file: /cvs/src/src/gdb/lin-lwp.c,v retrieving revision 1.47 diff -u -p -r1.47 lin-lwp.c --- lin-lwp.c 19 Jun 2003 22:52:03 -0000 1.47 +++ lin-lwp.c 17 Aug 2003 17:46:10 -0000 @@ -324,6 +324,8 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver gdb_assert (pid == GET_LWP (ptid) && WIFSTOPPED (status) && WSTOPSIG (status)); + child_post_attach (pid); + lp->stopped = 1; if (debug_lin_lwp) @@ -1067,6 +1069,10 @@ child_wait (ptid_t ptid, struct target_w return minus_one_ptid; } + /* Handle GNU/Linux's extended waitstatus for trace events. */ + if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + return linux_handle_extended_wait (pid, status, ourstatus); + store_waitstatus (ourstatus, status); return pid_to_ptid (pid); } @@ -1488,6 +1494,14 @@ retry: else trap_ptid = null_ptid; + /* Handle GNU/Linux's extended waitstatus for trace events. */ + if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + { + linux_handle_extended_wait (ptid_get_pid (trap_ptid), + status, ourstatus); + return trap_ptid; + } + store_waitstatus (ourstatus, status); return (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid))); } @@ -1657,6 +1671,12 @@ init_lin_lwp_ops (void) lin_lwp_ops.to_mourn_inferior = lin_lwp_mourn_inferior; lin_lwp_ops.to_thread_alive = lin_lwp_thread_alive; lin_lwp_ops.to_pid_to_str = lin_lwp_pid_to_str; + lin_lwp_ops.to_post_startup_inferior = child_post_startup_inferior; + lin_lwp_ops.to_post_attach = child_post_attach; + lin_lwp_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint; + lin_lwp_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint; + lin_lwp_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint; + lin_lwp_ops.to_stratum = thread_stratum; lin_lwp_ops.to_has_thread_control = tc_schedlock; lin_lwp_ops.to_magic = OPS_MAGIC; Index: linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.c,v retrieving revision 1.3 diff -u -p -r1.3 linux-nat.c --- linux-nat.c 19 Jun 2003 22:52:03 -0000 1.3 +++ linux-nat.c 17 Aug 2003 17:46:10 -0000 @@ -56,6 +56,8 @@ #define __WALL 0x40000000 /* Wait for any child. */ #endif +extern struct target_ops child_ops; + struct simple_pid_list { int pid; @@ -189,13 +191,147 @@ linux_supports_tracefork (void) } \f +void +linux_enable_event_reporting (ptid_t ptid) +{ + int pid = ptid_get_pid (ptid); + int options; + + if (! linux_supports_tracefork ()) + return; + + options = PTRACE_O_TRACEFORK; + + ptrace (PTRACE_SETOPTIONS, pid, 0, options); +} + +void +child_post_attach (int pid) +{ + linux_enable_event_reporting (pid_to_ptid (pid)); +} + +void +linux_child_post_startup_inferior (ptid_t ptid) +{ + linux_enable_event_reporting (ptid); +} + +#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR +void +child_post_startup_inferior (ptid_t ptid) +{ + linux_child_post_startup_inferior (ptid); +} +#endif + int -child_insert_fork_catchpoint (int pid) +child_follow_fork (int follow_child) { - if (linux_supports_tracefork ()) - error ("Fork catchpoints have not been implemented yet."); + ptid_t last_ptid; + struct target_waitstatus last_status; + int parent_pid, child_pid; + + get_last_target_status (&last_ptid, &last_status); + parent_pid = ptid_get_pid (last_ptid); + child_pid = last_status.value.related_pid; + + if (! follow_child) + { + /* We're already attached to the parent, by default. */ + + /* Before detaching from the child, remove all breakpoints from + it. (This won't actually modify the breakpoint list, but will + physically remove the breakpoints from the child.) */ + detach_breakpoints (child_pid); + + fprintf_filtered (gdb_stdout, + "Detaching after fork from child process %d.\n", + child_pid); + + ptrace (PTRACE_DETACH, child_pid, 0, 0); + } else + { + char child_pid_spelling[40]; + + /* Needed to keep the breakpoint lists in sync. */ + detach_breakpoints (child_pid); + + /* Before detaching from the parent, remove all breakpoints from it. */ + remove_breakpoints (); + + fprintf_filtered (gdb_stdout, + "Attaching after fork to child process %d.\n", + child_pid); + + target_detach (NULL, 0); + + inferior_ptid = pid_to_ptid (child_pid); + push_target (&child_ops); + + /* Reset breakpoints in the child as appropriate. */ + follow_inferior_reset_breakpoints (); + } + + return 0; +} + +ptid_t +linux_handle_extended_wait (int pid, int status, + struct target_waitstatus *ourstatus) +{ + int event = status >> 16; + + if (event == PTRACE_EVENT_CLONE) + internal_error (__FILE__, __LINE__, + "unexpected clone event"); + + if (event == PTRACE_EVENT_FORK) + { + unsigned long new_pid; + int ret; + + ptrace (PTRACE_GETEVENTMSG, pid, 0, &new_pid); + + /* If we haven't already seen the new PID stop, wait for it now. */ + if (! pull_pid_from_list (&stopped_pids, new_pid)) + { + /* The new child has a pending SIGSTOP. We can't affect it until it + hits the SIGSTOP, but we're already attached. + + It won't be a clone (we didn't ask for clones in the event mask) + so we can just call waitpid and wait for the SIGSTOP. */ + do { + ret = waitpid (new_pid, &status, 0); + } while (ret == -1 && errno == EINTR); + if (ret == -1) + perror_with_name ("waiting for new child"); + else if (ret != new_pid) + internal_error (__FILE__, __LINE__, + "wait returned unexpected PID %d", ret); + else if (!WIFSTOPPED (status) || WSTOPSIG (status) != SIGSTOP) + internal_error (__FILE__, __LINE__, + "wait returned unexpected status 0x%x", status); + } + + ourstatus->kind = TARGET_WAITKIND_FORKED; + ourstatus->value.related_pid = new_pid; + return inferior_ptid; + } + + internal_error (__FILE__, __LINE__, + "unknown ptrace event %d", event); +} + +\f +int +child_insert_fork_catchpoint (int pid) +{ + if (! linux_supports_tracefork ()) error ("Your system does not support fork catchpoints."); + + return 0; } int @@ -216,4 +352,43 @@ child_insert_exec_catchpoint (int pid) error ("Your system does not support exec catchpoints."); } +void +kill_inferior (void) +{ + int status; + int pid = PIDGET (inferior_ptid); + struct target_waitstatus last; + ptid_t last_ptid; + int ret; + + if (pid == 0) + return; + + /* If we're stopped while forking and we haven't followed yet, kill the + other task. We need to do this first because the parent will be + sleeping if this is a vfork. */ + + get_last_target_status (&last_ptid, &last); + if (last.kind == TARGET_WAITKIND_FORKED + || last.kind == TARGET_WAITKIND_VFORKED) + { + ptrace (PT_KILL, last.value.related_pid); + ptrace_wait (null_ptid, &status); + } + + /* Kill the current process. */ + ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0); + ret = ptrace_wait (null_ptid, &status); + + /* We might get a SIGCHLD instead of an exit status. This is + aggravated by the first kill above - a child has just died. */ + + while (ret == pid && WIFSTOPPED (status)) + { + ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0); + ret = ptrace_wait (null_ptid, &status); + } + + target_mourn_inferior (); +} Index: linux-nat.h =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.h,v retrieving revision 1.2 diff -u -p -r1.2 linux-nat.h --- linux-nat.h 20 Jun 2003 04:04:43 -0000 1.2 +++ linux-nat.h 17 Aug 2003 17:46:10 -0000 @@ -65,7 +65,12 @@ extern int linux_proc_xfer_memory (CORE_ int write, struct mem_attrib *attrib, struct target_ops *target); +/* linux-nat functions for handling fork events. */ extern void linux_record_stopped_pid (int pid); +extern void linux_enable_event_reporting (ptid_t ptid); +extern ptid_t linux_handle_extended_wait (int pid, int status, + struct target_waitstatus *ourstatus); +extern void linux_child_post_startup_inferior (ptid_t ptid); /* Iterator function for lin-lwp's lwp list. */ struct lwp_info *iterate_over_lwps (int (*callback) (struct lwp_info *, Index: config/nm-linux.h =================================================================== RCS file: /cvs/src/src/gdb/config/nm-linux.h,v retrieving revision 1.18 diff -u -p -r1.18 nm-linux.h --- config/nm-linux.h 19 Jun 2003 22:52:04 -0000 1.18 +++ config/nm-linux.h 17 Aug 2003 17:46:10 -0000 @@ -73,3 +73,7 @@ extern void lin_thread_get_thread_signal #define CHILD_INSERT_FORK_CATCHPOINT #define CHILD_INSERT_VFORK_CATCHPOINT #define CHILD_INSERT_EXEC_CATCHPOINT +#define CHILD_POST_STARTUP_INFERIOR +#define CHILD_POST_ATTACH +#define CHILD_FOLLOW_FORK +#define KILL_INFERIOR Index: config/i386/nm-linux.h =================================================================== RCS file: /cvs/src/src/gdb/config/i386/nm-linux.h,v retrieving revision 1.19 diff -u -p -r1.19 nm-linux.h --- config/i386/nm-linux.h 9 Nov 2002 21:31:12 -0000 1.19 +++ config/i386/nm-linux.h 17 Aug 2003 17:46:10 -0000 @@ -82,4 +82,13 @@ extern int cannot_store_register (int re /* Override child_resume in `infptrace.c'. */ #define CHILD_RESUME +/* `linux-nat.c' and `i386-nat.c' have their own versions of + child_post_startup_inferior. Define this to use the copy in + `i386-linux-nat.c' instead, which calls both. + + NOTE drow/2003-08-17: This is ugly beyond words, but properly + fixing it will require some serious surgery. Ideally the target + stack could be used for this. */ +#define LINUX_CHILD_POST_STARTUP_INFERIOR + #endif /* nm-linux.h */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-08-17 18:22 ` Daniel Jacobowitz @ 2003-08-18 9:09 ` Michal Ludvig 2003-08-18 12:59 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Michal Ludvig @ 2003-08-18 9:09 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: GDB Patches, Mark Kettenis Daniel Jacobowitz told me that: > 2003-08-17 Daniel Jacobowitz <drow@mvista.com> > > * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): > Define. > * i386-linux-nat.c: Include "linux-nat.h". > (child_post_startup_inferior): New function. > * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. > * linux-nat.c (linux_enable_event_reporting): New function. > (child_post_attach, linux_child_post_startup_inferior) > (child_post_startup_inferior, child_follow_fork) > (linux_handle_extended_wait, kill_inferior): New functions. Hi Daniel, this change broke build on AMD64. Per-se I'm getting linker error: libgdb.a(linux-nat.o)(.text+0x3e8): In function `child_post_startup_inferior': ../../gdb-6.0/gdb/linux-nat.c:223: multiple definition of `child_post_startup_inferior' libgdb.a(i386-nat.o)(.text+0x52):../../gdb-6.0/gdb/i386-nat.c:238: first defined here /usr/lib64/gcc-lib/x86_64-suse-linux/3.3/../../../../x86_64-suse-linux/bin/ld: Warning: size of symbol `child_post_startup_inferior' changed from 11 in libgdb.a(i386-nat.o) to 41 in libgdb.a(i386-nat.o) collect2: ld returned 1 exit status make: *** [gdb] Error 1 I.e. `child_post_startup_inferior' is defined twice. When I define LINUX_CHILD_POST_STARTUP_INFERIOR in config/i386/nm-x86-64linux.h I get: libgdb.a(inftarg.o)(.text+0x692): In function `init_child_ops': ../../gdb-6.0/gdb/inftarg.c:593: undefined reference to `child_post_startup_inferior' libgdb.a(lin-lwp.o)(.text+0x3f76): In function `init_lin_lwp_ops': ../../gdb-6.0/gdb/lin-lwp.c:1675: undefined reference to `child_post_startup_inferior' I.e. it's never defined. The problem seems to be that child_post_startup_inferior() in both i386-nat.c and linux-nat.c is #ifNdef-ed, i.e. either both undefined or both defined. Is that intended? However the proper fix for amd64 seems to be: Index: x86-64-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v retrieving revision 1.23.6.2 diff -u -p -r1.23.6.2 x86-64-linux-nat.c --- x86-64-linux-nat.c 17 Jul 2003 12:51:55 -0000 1.23.6.2 +++ x86-64-linux-nat.c 18 Aug 2003 09:05:51 -0000 @@ -347,3 +347,9 @@ ps_get_thread_area (const struct ps_proc return PS_ERR; /* ptrace failed. */ } +void +child_post_startup_inferior (ptid_t ptid) +{ + i386_cleanup_dregs (); + linux_child_post_startup_inferior (ptid); +} Right? OK to apply? Michal Ludvig -- * SuSE CR, s.r.o * mludvig@suse.cz * (+420) 296.545.373 * http://www.suse.cz ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-08-18 9:09 ` Michal Ludvig @ 2003-08-18 12:59 ` Daniel Jacobowitz 2003-08-18 13:11 ` Michal Ludvig 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2003-08-18 12:59 UTC (permalink / raw) To: Michal Ludvig; +Cc: GDB Patches, Mark Kettenis On Mon, Aug 18, 2003 at 11:09:53AM +0200, Michal Ludvig wrote: > Daniel Jacobowitz told me that: > > > 2003-08-17 Daniel Jacobowitz <drow@mvista.com> > > > > * config/i386/nm-linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): > > Define. > > * i386-linux-nat.c: Include "linux-nat.h". > > (child_post_startup_inferior): New function. > > * i386-nat.c (child_post_startup_inferior): Wrap in #ifdef. > > * linux-nat.c (linux_enable_event_reporting): New function. > > (child_post_attach, linux_child_post_startup_inferior) > > (child_post_startup_inferior, child_follow_fork) > > (linux_handle_extended_wait, kill_inferior): New functions. > > Hi Daniel, > this change broke build on AMD64. Per-se I'm getting linker error: > > libgdb.a(linux-nat.o)(.text+0x3e8): In function > `child_post_startup_inferior': > ../../gdb-6.0/gdb/linux-nat.c:223: multiple definition of > `child_post_startup_inferior' > libgdb.a(i386-nat.o)(.text+0x52):../../gdb-6.0/gdb/i386-nat.c:238: first > defined here > /usr/lib64/gcc-lib/x86_64-suse-linux/3.3/../../../../x86_64-suse-linux/bin/ld: > Warning: size of symbol `child_post_startup_inferior' changed from 11 in > libgdb.a(i386-nat.o) to 41 in libgdb.a(i386-nat.o) > collect2: ld returned 1 exit status > make: *** [gdb] Error 1 > > I.e. `child_post_startup_inferior' is defined twice. > > When I define LINUX_CHILD_POST_STARTUP_INFERIOR in > config/i386/nm-x86-64linux.h I get: > > libgdb.a(inftarg.o)(.text+0x692): In function `init_child_ops': > ../../gdb-6.0/gdb/inftarg.c:593: undefined reference to > `child_post_startup_inferior' > libgdb.a(lin-lwp.o)(.text+0x3f76): In function `init_lin_lwp_ops': > ../../gdb-6.0/gdb/lin-lwp.c:1675: undefined reference to > `child_post_startup_inferior' > > I.e. it's never defined. > > The problem seems to be that child_post_startup_inferior() in both > i386-nat.c and linux-nat.c is #ifNdef-ed, i.e. either both undefined or > both defined. Is that intended? Take a look at the third copy - it's in i386-linux-nat.c. Then take a look at the annoyed comment in i386/nm-linux.h. > However the proper fix for amd64 seems to be: > > Index: x86-64-linux-nat.c > =================================================================== > RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v > retrieving revision 1.23.6.2 > diff -u -p -r1.23.6.2 x86-64-linux-nat.c > --- x86-64-linux-nat.c 17 Jul 2003 12:51:55 -0000 1.23.6.2 > +++ x86-64-linux-nat.c 18 Aug 2003 09:05:51 -0000 > @@ -347,3 +347,9 @@ ps_get_thread_area (const struct ps_proc > return PS_ERR; /* ptrace failed. */ > } > > +void > +child_post_startup_inferior (ptid_t ptid) > +{ > + i386_cleanup_dregs (); > + linux_child_post_startup_inferior (ptid); > +} > > Right? OK to apply? Along with defining LINUX_CHILD_POST_STARTUP_INFERIOR, I assume? Yes, this is OK. Sorry about breaking amd64. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFA: Actual support for tracing forks on GNU/Linux 2003-08-18 12:59 ` Daniel Jacobowitz @ 2003-08-18 13:11 ` Michal Ludvig 0 siblings, 0 replies; 9+ messages in thread From: Michal Ludvig @ 2003-08-18 13:11 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: GDB Patches, Mark Kettenis [-- Attachment #1: Type: text/plain, Size: 982 bytes --] Daniel Jacobowitz told me that: > On Mon, Aug 18, 2003 at 11:09:53AM +0200, Michal Ludvig wrote: >>Index: x86-64-linux-nat.c >>=================================================================== >>RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v >>retrieving revision 1.23.6.2 >>diff -u -p -r1.23.6.2 x86-64-linux-nat.c >>--- x86-64-linux-nat.c 17 Jul 2003 12:51:55 -0000 1.23.6.2 >>+++ x86-64-linux-nat.c 18 Aug 2003 09:05:51 -0000 >>@@ -347,3 +347,9 @@ ps_get_thread_area (const struct ps_proc >> return PS_ERR; /* ptrace failed. */ >> } >> >>+void >>+child_post_startup_inferior (ptid_t ptid) >>+{ >>+ i386_cleanup_dregs (); >>+ linux_child_post_startup_inferior (ptid); >>+} >> >>Right? OK to apply? > > Along with defining LINUX_CHILD_POST_STARTUP_INFERIOR, I assume? Yes, > this is OK. Sorry about breaking amd64. Thanks, committed the attached. Michal Ludvig -- * SuSE CR, s.r.o * mludvig@suse.cz * (+420) 296.545.373 * http://www.suse.cz [-- Attachment #2: cpsi-2.diff --] [-- Type: text/plain, Size: 2145 bytes --] Index: ChangeLog =================================================================== RCS file: /cvs/src/src/gdb/ChangeLog,v retrieving revision 1.4439.2.107 diff -u -p -r1.4439.2.107 ChangeLog --- ChangeLog 17 Aug 2003 18:53:12 -0000 1.4439.2.107 +++ ChangeLog 18 Aug 2003 13:08:44 -0000 @@ -1,3 +1,10 @@ +2003-08-18 Michal Ludvig <mludvig@suse.cz> + + * config/i386/nm-x86-64linux.h (LINUX_CHILD_POST_STARTUP_INFERIOR): + Define. + * i386-linux-nat.c: Include "linux-nat.h". + (child_post_startup_inferior): New function. + 2003-08-17 Daniel Jacobowitz <drow@mvista.com> * lin-lwp.c (child_wait): Call linux_record_stopped_pid. Index: x86-64-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v retrieving revision 1.23.6.2 diff -u -p -r1.23.6.2 x86-64-linux-nat.c --- x86-64-linux-nat.c 17 Jul 2003 12:51:55 -0000 1.23.6.2 +++ x86-64-linux-nat.c 18 Aug 2003 13:08:44 -0000 @@ -25,6 +25,7 @@ #include "inferior.h" #include "gdbcore.h" #include "regcache.h" +#include "linux-nat.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -347,3 +348,9 @@ ps_get_thread_area (const struct ps_proc return PS_ERR; /* ptrace failed. */ } +void +child_post_startup_inferior (ptid_t ptid) +{ + i386_cleanup_dregs (); + linux_child_post_startup_inferior (ptid); +} Index: config/i386/nm-x86-64linux.h =================================================================== RCS file: /cvs/src/src/gdb/config/i386/nm-x86-64linux.h,v retrieving revision 1.3 diff -u -p -r1.3 nm-x86-64linux.h --- config/i386/nm-x86-64linux.h 19 Jun 2003 15:04:58 -0000 1.3 +++ config/i386/nm-x86-64linux.h 18 Aug 2003 13:08:44 -0000 @@ -61,4 +61,9 @@ extern unsigned long x86_64_linux_dr_get /* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */ #define FETCH_INFERIOR_REGISTERS +/* `linux-nat.c' and `i386-nat.c' have their own versions of + child_post_startup_inferior. Define this to use the copy in + `x86-86-linux-nat.c' instead, which calls both. */ +#define LINUX_CHILD_POST_STARTUP_INFERIOR + #endif /* NM_X86_64_LINUX_H */ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2003-08-18 13:11 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-06-18 23:29 RFA: Actual support for tracing forks on GNU/Linux Daniel Jacobowitz 2003-06-28 16:35 ` Daniel Jacobowitz 2003-07-09 21:57 ` Daniel Jacobowitz 2003-07-24 18:48 ` Daniel Jacobowitz 2003-08-10 16:11 ` Mark Kettenis 2003-08-17 18:22 ` Daniel Jacobowitz 2003-08-18 9:09 ` Michal Ludvig 2003-08-18 12:59 ` Daniel Jacobowitz 2003-08-18 13:11 ` Michal Ludvig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox