diff options
author | Don Breazeal <donb@codesourcery.com> | 2015-05-12 09:52:45 -0700 |
---|---|---|
committer | Don Breazeal <donb@codesourcery.com> | 2015-05-12 09:52:45 -0700 |
commit | c269dbdb603216de2be52f07f26e65ead7e11c7b (patch) | |
tree | 58e3c78262fd63c0e2f937350b1020f461b06554 /gdb/remote.c | |
parent | 3a8a0396bed4e9dd87c2df0f68386a0f04dfc824 (diff) | |
download | gdb-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.c | 22 |
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; |