summaryrefslogtreecommitdiff
path: root/gdb/gdbserver/remote-utils.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/gdbserver/remote-utils.c
parent3a8a0396bed4e9dd87c2df0f68386a0f04dfc824 (diff)
downloadbinutils-gdb-c269dbdb603216de2be52f07f26e65ead7e11c7b.tar.gz
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/gdbserver/remote-utils.c')
-rw-r--r--gdb/gdbserver/remote-utils.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 60783489b8a..bb3145683bb 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1115,16 +1115,20 @@ prepare_resume_reply (char *buf, ptid_t ptid,
{
case TARGET_WAITKIND_STOPPED:
case TARGET_WAITKIND_FORKED:
+ case TARGET_WAITKIND_VFORKED:
{
struct thread_info *saved_thread;
const char **regp;
struct regcache *regcache;
- if (status->kind == TARGET_WAITKIND_FORKED && report_fork_events)
+ if ((status->kind == TARGET_WAITKIND_FORKED && report_fork_events)
+ || (status->kind == TARGET_WAITKIND_VFORKED && report_vfork_events))
{
enum gdb_signal signal = GDB_SIGNAL_TRAP;
+ const char *event = (status->kind == TARGET_WAITKIND_FORKED
+ ? "fork" : "vfork");
- sprintf (buf, "T%02xfork:", signal);
+ sprintf (buf, "T%02x%s:", signal, event);
buf += strlen (buf);
buf = write_ptid (buf, status->value.related_pid);
strcat (buf, ";");
@@ -1244,6 +1248,16 @@ prepare_resume_reply (char *buf, ptid_t ptid,
else
sprintf (buf, "X%02x", status->value.sig);
break;
+ case TARGET_WAITKIND_VFORK_DONE:
+ if (report_vfork_events)
+ {
+ enum gdb_signal signal = GDB_SIGNAL_TRAP;
+
+ sprintf (buf, "T%02xvforkdone:;", signal);
+ }
+ else
+ sprintf (buf, "T%02x", GDB_SIGNAL_0);
+ break;
default:
error ("unhandled waitkind");
break;