This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]