This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Preferred thread event reporting: remote target / gdbserver
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 14 Aug 2008 22:40:27 +0200 (CEST)
- Subject: [rfc] Preferred thread event reporting: remote target / gdbserver
Hello,
this patch adds support for preferred thread event reporting to gdbserver
as well, along the lines of previous Linux-native patch.
One additional consideration here is how to pass the information *which*
thread should be preferred across the remote protocol. The solution
implemented in this patch does not require any changes to the protocol
itself, it simply adds some additional meaning to existing vCont commands.
The basic idea is simple: a vCont command may name multiple actions; the
thread specified in the *first* action of a vCont command is the preferred
thread. In most cases, GDB would already use vCont like this; there is
just one situation (a general "continue") where GDB used to simply specify
"c" as action list -- this is changed to "c:NNN;c" where NNN denotes the
current (preferred) thread.
This should be completely compatible with both older servers and clients
of the remote protocol.
Tested on powerpc-linux and powerpc64-linux in local gdbserver mode.
OK for mainline?
Bye,
Ulrich
ChangeLog:
* remote.c (remote_vcont_resume): Always name preferred thread
in vCont request.
gdbserver/ChangeLog:
* linux-low.c (preferred_status_pending_p): New function.
(linux_wait): Call it.
(linux_set_resume_request): Set preferred thread flag.
* linux-low.h (struct process_info): New member "preferred".
diff -urNp gdb-orig/gdb/gdbserver/linux-low.c gdb-head/gdb/gdbserver/linux-low.c
--- gdb-orig/gdb/gdbserver/linux-low.c 2008-08-06 00:11:59.000000000 +0200
+++ gdb-head/gdb/gdbserver/linux-low.c 2008-08-14 19:55:35.820787425 +0200
@@ -906,6 +906,34 @@ linux_wait_for_event (struct thread_info
return 0;
}
+/* If the preferred thread now has status pending, prefer to report it,
+ and make the current thread status pending instead. */
+static int
+preferred_status_pending_p (struct inferior_list_entry *entry, void *w)
+{
+ struct process_info *process = (struct process_info *) entry;
+ int *wstat = (int *)w;
+
+ if (process->preferred && process->status_pending_p)
+ {
+ struct process_info *current_process
+ = get_thread_process (current_inferior);
+
+ current_process->status_pending_p = 1;
+ current_process->status_pending = *wstat;
+
+ process->status_pending_p = 0;
+ *wstat = process->status_pending;
+
+ current_inferior = (struct thread_info *)
+ find_inferior_id (&all_threads, process->lwpid);
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* Wait for process, returns status. */
static unsigned char
@@ -939,6 +967,10 @@ retry:
w = linux_wait_for_event (child);
stop_all_processes ();
+ /* If the preferred thread now has some status, report it in preference
+ to the status of the thread initially found by linux_wait_for_event. */
+ find_inferior (&all_processes, preferred_status_pending_p, &w);
+
if (must_set_ptrace_flags)
{
ptrace (PTRACE_SETOPTIONS, inferior_pid, 0, PTRACE_O_TRACECLONE);
@@ -1232,6 +1264,9 @@ linux_set_resume_request (struct inferio
ndx++;
process->resume = &resume_ptr[ndx];
+
+ /* The first thread mentioned in the resume list is the preferred one. */
+ process->preferred = (ndx == 0 && resume_ptr[ndx].thread == entry->id);
}
/* This function is called once per thread. We check the thread's resume
diff -urNp gdb-orig/gdb/gdbserver/linux-low.h gdb-head/gdb/gdbserver/linux-low.h
--- gdb-orig/gdb/gdbserver/linux-low.h 2008-02-28 06:54:09.000000000 +0100
+++ gdb-head/gdb/gdbserver/linux-low.h 2008-08-14 19:35:05.816137035 +0200
@@ -120,6 +120,9 @@ struct process_info
was a single-step. */
int stepping;
+ /* Non-zero if this is the thread preferred for event reporting. */
+ int preferred;
+
/* If this is non-zero, it points to a chain of signals which need to
be delivered to this process. */
struct pending_signals *pending_signals;
diff -urNp gdb-orig/gdb/remote.c gdb-head/gdb/remote.c
--- gdb-orig/gdb/remote.c 2008-08-14 17:55:51.605385128 +0200
+++ gdb-head/gdb/remote.c 2008-08-14 21:00:54.570255549 +0200
@@ -3170,7 +3170,8 @@ remote_vcont_resume (ptid_t ptid, int st
about overflowing BUF. Should there be a generic
"multi-part-packet" packet? */
- if (ptid_equal (ptid, magic_null_ptid))
+ if (ptid_equal (ptid, magic_null_ptid)
+ || ptid_equal (inferior_ptid, magic_null_ptid))
{
/* MAGIC_NULL_PTID means that we don't have any active threads,
so we don't have any TID numbers the inferior will
@@ -3196,7 +3197,7 @@ remote_vcont_resume (ptid_t ptid, int st
else if (siggnal != TARGET_SIGNAL_0)
outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal, tid);
else
- outbuf = xstrprintf ("vCont;c");
+ outbuf = xstrprintf ("vCont;c:%x;c", tid);
}
else
{
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com