aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
authorDon Breazeal <donb@codesourcery.com>2015-05-12 09:52:45 -0700
committerDon Breazeal <donb@codesourcery.com>2015-05-12 09:52:45 -0700
commitc269dbdb603216de2be52f07f26e65ead7e11c7b (patch)
tree58e3c78262fd63c0e2f937350b1020f461b06554 /gdb/remote.c
parent3a8a0396bed4e9dd87c2df0f68386a0f04dfc824 (diff)
downloadgdb-c269dbdb603216de2be52f07f26e65ead7e11c7b.zip
gdb-c269dbdb603216de2be52f07f26e65ead7e11c7b.tar.gz
gdb-c269dbdb603216de2be52f07f26e65ead7e11c7b.tar.bz2
Extended-remote follow vfork
This patch implements follow-fork for vfork on extended-remote Linux targets. The implementation follows the native implementation as much as possible. Most of the work is done on the GDB side in the existing code now in infrun.c. GDBserver just has to report the events and do a little bookkeeping. Implementation includes: * enabling VFORK events by adding ptrace options for VFORK and VFORK_DONE to linux-low.c:linux_low_ptrace_options. * handling VFORK and VFORK_DONE events in linux-low.c:handle_extended_wait and reporting them to GDB. * including VFORK and VFORK_DONE events in the predicate linux-low.c:extended_event_reported. * adding support for VFORK and VFORK_DONE events in RSP by adding stop reasons "vfork" and "vforkdone" to the 'T' Stop Reply Packet in both gdbserver/remote-utils.c and gdb/remote.c. Tested on x64 Ubuntu Lucid, native, remote, extended-remote. gdb/gdbserver/ChangeLog: * linux-low.c (handle_extended_wait): Handle PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK_DONE. (linux_low_ptrace_options, extended_event_reported): Add vfork events. * remote-utils.c (prepare_resume_reply): New stop reasons "vfork" and "vforkdone" for RSP 'T' Stop Reply Packet. * server.h (report_vfork_events): Declare global variable. gdb/ChangeLog: * remote.c (remove_vfork_event_p): New function. (remote_follow_fork): Add vfork event type to event checking. (remote_parse_stop_reply): New stop reasons "vfork" and "vforkdone" for RSP 'T' Stop Reply Packet.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 390d30d..df8fca3 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1470,6 +1470,14 @@ remote_fork_event_p (struct remote_state *rs)
return packet_support (PACKET_fork_event_feature) == PACKET_ENABLE;
}
+/* Returns true if vfork events are supported. */
+
+static int
+remote_vfork_event_p (struct remote_state *rs)
+{
+ return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE;
+}
+
/* Tokens for use by the asynchronous signal handlers for SIGINT. */
static struct async_signal_handler *async_sigint_remote_twice_token;
static struct async_signal_handler *async_sigint_remote_token;
@@ -4537,8 +4545,10 @@ remote_follow_fork (struct target_ops *ops, int follow_child,
int detach_fork)
{
struct remote_state *rs = get_remote_state ();
+ enum target_waitkind kind = inferior_thread ()->pending_follow.kind;
- if (remote_fork_event_p (rs))
+ if ((kind == TARGET_WAITKIND_FORKED && remote_fork_event_p (rs))
+ || (kind == TARGET_WAITKIND_VFORKED && remote_vfork_event_p (rs)))
{
/* When following the parent and detaching the child, we detach
the child here. For the case of following the child and
@@ -5727,6 +5737,16 @@ Packet: '%s'\n"),
event->ws.value.related_pid = read_ptid (++p1, &p);
event->ws.kind = TARGET_WAITKIND_FORKED;
}
+ else if (strncmp (p, "vfork", p1 - p) == 0)
+ {
+ event->ws.value.related_pid = read_ptid (++p1, &p);
+ event->ws.kind = TARGET_WAITKIND_VFORKED;
+ }
+ else if (strncmp (p, "vforkdone", p1 - p) == 0)
+ {
+ event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
+ p = skip_to_semicolon (p1 + 1);
+ }
else
{
ULONGEST pnum;