Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* make the remote target store thread ids in ptid_t.tid
@ 2008-06-25 23:11 Pedro Alves
  2008-06-26  3:21 ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Pedro Alves @ 2008-06-25 23:11 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1453 bytes --]

Hi,

Currently, remote.c stores thread ids in the ptid.pid field, which
isn't good for multi-process support.  We need to be able to store
the {pid,tid} tuple in ptids to uniquely identify threads, when we
go multi-process.

So, I've made this patch to switch it into using ptid.tid, so
we get the ptid.pid field for storing real pids.

There are several hacks that we have to preserve due to the way
the protocol worked before vCont was around, and due to sometimes
GDB not knowing about the remote threads.  One of those is the
MAGIC_NULL_PTID "mechanism" which is used to have something
non-null in inferior_ptid when connected with stubs that
don't support any of the optional remote protocol extensions
related to thread support (T AA thread:TID, qC, qfThreadInfo, etc.).

I've tested this extensivelly by talking to a native gdbserver,
and native gdbserver with vCont disabled, and then also with a
gdbserver with vCont and all thread related packets and fields
disabled, to simulate old stubs and stubs that don't support
threads at all.

I didn't see any regression, and diffing the remote protocol
debug output logs in the cripled gdbserver cases showed no
differences (apart from thread ids, of course).

Does it look OK?

A good thing is that magic_null_ptid actually becomes safe and
unambigous, because a ptid_equal with a ptid of a real
thread id will always return false.  I'm relying on that
property on the next patch.

-- 
Pedro Alves

[-- Attachment #2: 001-remote_pid_tid.diff --]
[-- Type: text/x-diff, Size: 19348 bytes --]

2008-06-25  Pedro Alves  <pedro@codesourcery.com>

	Use ptid_t.tid to store thread ids instead of ptid_t.pid.

	* remote.c (magic_null_ptid, not_sent_ptid, any_thread_ptid): New
	globals.
	(general_thread, continue_thread): Change type to ptid_t.
	(record_currthread): Take a ptid_t parameter instead of an
	integer.
	(MAGIC_NULL_PID): Delete.
	(set_thread): Take a ptid_t parameter and adjust.
	(set_general_thread, set_continue_thread): New.
	(remote_thread_alive, remote_newthread_step)
	(remote_current_thread, remote_find_new_threads)
	(remote_threads_info, remote_start_remote, remote_vcont_resume)
	(remote_resume_1, remote_wait, extended_remote_create_inferior_1)
	(threadalive_test, remote_pid_to_str)
	(remote_get_thread_local_address): Adjust.
	(_initialize_remote): Initialize magic_null_ptid, not_sent_ptid
	and any_thread_ptid.

---
 gdb/remote.c |  238 +++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 151 insertions(+), 87 deletions(-)

Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2008-06-25 11:22:37.000000000 +0100
+++ src/gdb/remote.c	2008-06-25 17:13:25.000000000 +0100
@@ -138,7 +138,8 @@ static void remote_interrupt_twice (int 
 
 static void interrupt_query (void);
 
-static void set_thread (int, int);
+static void set_general_thread (struct ptid ptid);
+static void set_continue_thread (struct ptid ptid);
 
 static int remote_thread_alive (ptid_t);
 
@@ -180,7 +181,7 @@ static ptid_t remote_current_thread (pti
 
 static void remote_find_new_threads (void);
 
-static void record_currthread (int currthread);
+static void record_currthread (ptid_t currthread);
 
 static int fromhex (int a);
 
@@ -1063,11 +1064,16 @@ static struct async_signal_handler *sigi
 
 \f
 
+static ptid_t magic_null_ptid;
+static ptid_t not_sent_ptid;
+static ptid_t any_thread_ptid;
+
+/* These are the threads which we last sent to the remote system.  The
+   TID member will be -1 for all or -2 for not sent yet.  */
+
+static ptid_t general_thread;
+static ptid_t continue_thread;
 
-/* These are the threads which we last sent to the remote system.
-   -1 for all or -2 for not sent yet.  */
-static int general_thread;
-static int continue_thread;
 
 /* Call this function as a result of
    1) A halt indication (T packet) containing a thread id
@@ -1076,14 +1082,14 @@ static int continue_thread;
  */
 
 static void
-record_currthread (int currthread)
+record_currthread (ptid_t currthread)
 {
   general_thread = currthread;
 
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
-  if (!in_thread_list (pid_to_ptid (currthread)))
-    add_thread (pid_to_ptid (currthread));
+  if (!in_thread_list (currthread))
+    add_thread (currthread);
 }
 
 static char *last_pass_packet;
@@ -1145,44 +1151,66 @@ remote_pass_signals (void)
     }
 }
 
-#define MAGIC_NULL_PID 42000
-
+/* If PTID is MAGIC_NULL_PTID, don't set any thread.  If PTID is
+   MINUS_ONE_PTID, set the thread to -1, so the stub returns the
+   thread.  If GEN is set, set the general thread, if not, then set
+   the step/continue thread.  */
 static void
-set_thread (int th, int gen)
+set_thread (struct ptid ptid, int gen)
 {
   struct remote_state *rs = get_remote_state ();
+  ptid_t state = gen ? general_thread : continue_thread;
   char *buf = rs->buf;
-  int state = gen ? general_thread : continue_thread;
+  char *endbuf = rs->buf + get_remote_packet_size ();
 
-  if (state == th)
+  if (ptid_equal (state, ptid))
     return;
 
-  buf[0] = 'H';
-  buf[1] = gen ? 'g' : 'c';
-  if (th == MAGIC_NULL_PID)
+  *buf++ = 'H';
+  *buf++ = gen ? 'g' : 'c';
+  if (ptid_equal (ptid, magic_null_ptid))
+    xsnprintf (buf, endbuf - buf, "0");
+  else if (ptid_equal (ptid, any_thread_ptid))
+    xsnprintf (buf, endbuf - buf, "0");
+  else if (ptid_equal (ptid, minus_one_ptid))
+    xsnprintf (buf, endbuf - buf, "-1");
+  else
     {
-      buf[2] = '0';
-      buf[3] = '\0';
+      int tid = ptid_get_tid (ptid);
+      if (tid < 0)
+	xsnprintf (buf, endbuf - buf, "-%x", -tid);
+      else
+	xsnprintf (buf, endbuf - buf, "%x", tid);
     }
-  else if (th < 0)
-    xsnprintf (&buf[2], get_remote_packet_size () - 2, "-%x", -th);
-  else
-    xsnprintf (&buf[2], get_remote_packet_size () - 2, "%x", th);
-  putpkt (buf);
+  putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
   if (gen)
-    general_thread = th;
+    general_thread = ptid;
   else
-    continue_thread = th;
+    continue_thread = ptid;
 }
+
+static void
+set_general_thread (struct ptid ptid)
+{
+  set_thread (ptid, 1);
+}
+
+static void
+set_continue_thread (struct ptid ptid)
+{
+  set_thread (ptid, 0);
+}
+
 \f
-/*  Return nonzero if the thread TH is still alive on the remote system.  */
+/*  Return nonzero if the thread PTID is still alive on the remote
+    system.  */
 
 static int
 remote_thread_alive (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
-  int tid = PIDGET (ptid);
+  int tid = ptid_get_tid (ptid);
 
   if (tid < 0)
     xsnprintf (rs->buf, get_remote_packet_size (), "T-%08x", -tid);
@@ -1802,7 +1830,7 @@ remote_get_threadlist (int startflag, th
 
 /* remote_find_new_threads retrieves the thread list and for each
    thread in the list, looks up the thread in GDB's internal list,
-   ading the thread if it does not already exist.  This involves
+   adding the thread if it does not already exist.  This involves
    getting partial thread lists from the remote target so, polling the
    quit_flag is required.  */
 
@@ -1853,9 +1881,8 @@ remote_threadlist_iterator (rmt_thread_a
 static int
 remote_newthread_step (threadref *ref, void *context)
 {
-  ptid_t ptid;
-
-  ptid = pid_to_ptid (threadref_to_int (ref));
+  int pid = ptid_get_pid (inferior_ptid);
+  ptid_t ptid = ptid_build (pid, 0, threadref_to_int (ref));
 
   if (!in_thread_list (ptid))
     add_thread (ptid);
@@ -1868,16 +1895,23 @@ static ptid_t
 remote_current_thread (ptid_t oldpid)
 {
   struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int tid;
+  int pid;
 
   putpkt ("qC");
   getpkt (&rs->buf, &rs->buf_size, 0);
   if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
-    /* Use strtoul here, so we'll correctly parse values whose highest
-       bit is set.  The protocol carries them as a simple series of
-       hex digits; in the absence of a sign, strtol will see such
-       values as positive numbers out of range for signed 'long', and
-       return LONG_MAX to indicate an overflow.  */
-    return pid_to_ptid (strtoul (&rs->buf[2], NULL, 16));
+    {
+      /* Use strtoul here, so we'll correctly parse values whose
+	 highest bit is set.  The protocol carries them as a simple
+	 series of hex digits; in the absence of a sign, strtol will
+	 see such values as positive numbers out of range for signed
+	 'long', and return LONG_MAX to indicate an overflow.  */
+      tid = strtoul (&rs->buf[2], NULL, 16);
+      pid = ptid_get_pid (oldpid);
+      return ptid_build (pid, 0, tid);
+    }
   else
     return oldpid;
 }
@@ -1891,7 +1925,8 @@ remote_find_new_threads (void)
 {
   remote_threadlist_iterator (remote_newthread_step, 0,
 			      CRAZY_MAX_THREADS);
-  if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)	/* ack ack ack */
+  if (ptid_equal (inferior_ptid, magic_null_ptid))
+    /* We don't know the current thread yet.  Query it.  */
     inferior_ptid = remote_current_thread (inferior_ptid);
 }
 
@@ -1908,6 +1943,8 @@ remote_threads_info (void)
   struct remote_state *rs = get_remote_state ();
   char *bufp;
   int tid;
+  int pid;
+  ptid_t new_thread;
 
   if (remote_desc == 0)		/* paranoia */
     error (_("Command can only be used when connected to the remote target."));
@@ -1930,8 +1967,10 @@ remote_threads_info (void)
 		     positive numbers out of range for signed 'long',
 		     and return LONG_MAX to indicate an overflow.  */
 		  tid = strtoul (bufp, &bufp, 16);
-		  if (tid != 0 && !in_thread_list (pid_to_ptid (tid)))
-		    add_thread (pid_to_ptid (tid));
+		  pid = ptid_get_pid (inferior_ptid);
+		  new_thread = ptid_build (pid, 0, tid);
+		  if (tid != 0 && !in_thread_list (new_thread))
+		    add_thread (new_thread);
 		}
 	      while (*bufp++ == ',');	/* comma-separated list */
 	      putpkt ("qsThreadInfo");
@@ -1974,8 +2013,8 @@ remote_threads_extra_info (struct thread
 
   if (use_threadextra_query)
     {
-      xsnprintf (rs->buf, get_remote_packet_size (), "qThreadExtraInfo,%x",
-		 PIDGET (tp->ptid));
+      xsnprintf (rs->buf, get_remote_packet_size (), "qThreadExtraInfo,%lx",
+		 ptid_get_tid (tp->ptid));
       putpkt (rs->buf);
       getpkt (&rs->buf, &rs->buf_size, 0);
       if (rs->buf[0] != 0)
@@ -1991,7 +2030,7 @@ remote_threads_extra_info (struct thread
   use_threadextra_query = 0;
   set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
     | TAG_MOREDISPLAY | TAG_DISPLAY;
-  int_to_threadref (&id, PIDGET (tp->ptid));
+  int_to_threadref (&id, ptid_get_tid (tp->ptid));
   if (remote_get_threadinfo (&id, set, &threadinfo))
     if (threadinfo.active)
       {
@@ -2251,7 +2290,7 @@ remote_start_remote (struct ui_out *uiou
     }
 
   /* Let the stub know that we want it to return the thread.  */
-  set_thread (-1, 0);
+  set_continue_thread (minus_one_ptid);
 
   /* Without this, some commands which require an active target
      (such as kill) won't work.  This variable serves (at least)
@@ -2260,7 +2299,7 @@ remote_start_remote (struct ui_out *uiou
      These functions should be split out into seperate variables,
      especially since GDB will someday have a notion of debugging
      several processes.  */
-  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+  inferior_ptid = magic_null_ptid;
 
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
@@ -2690,8 +2729,8 @@ remote_open_1 (char *name, int from_tty,
   init_all_packet_configs ();
   rs->explicit_packet_size = 0;
 
-  general_thread = -2;
-  continue_thread = -2;
+  general_thread = not_sent_ptid;
+  continue_thread = not_sent_ptid;
 
   /* Probe for ability to use "ThreadInfo" query, as required.  */
   use_threadinfo_query = 1;
@@ -2891,6 +2930,10 @@ extended_remote_attach_1 (struct target_
 
   target_mark_running (target);
   inferior_ptid = pid_to_ptid (pid);
+
+  /* Now, if we have thread information, update inferior_ptid.  */
+  inferior_ptid = remote_current_thread (inferior_ptid);
+
   attach_flag = 1;
 
   /* Next, if the target can specify a description, read it.  We do
@@ -3020,10 +3063,10 @@ remote_vcont_probe (struct remote_state 
 
 /* Resume the remote inferior by using a "vCont" packet.  The thread
    to be resumed is PTID; STEP and SIGGNAL indicate whether the
-   resumed thread should be single-stepped and/or signalled.  If PTID's
-   PID is -1, then all threads are resumed; the thread to be stepped and/or
-   signalled is given in the global INFERIOR_PTID.  This function returns
-   non-zero iff it resumes the inferior.
+   resumed thread should be single-stepped and/or signalled.  If PTID
+   equals minus_one_ptid, then all threads are resumed; the thread to
+   be stepped and/or signalled is given in the global INFERIOR_PTID.
+   This function returns non-zero iff it resumes the inferior.
 
    This function issues a strict subset of all possible vCont commands at the
    moment.  */
@@ -3032,7 +3075,6 @@ static int
 remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
-  int pid = PIDGET (ptid);
   char *outbuf;
   struct cleanup *old_cleanup;
 
@@ -3046,11 +3088,12 @@ remote_vcont_resume (ptid_t ptid, int st
      about overflowing BUF.  Should there be a generic
      "multi-part-packet" packet?  */
 
-  if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)
+  if (ptid_equal (ptid, magic_null_ptid))
     {
-      /* MAGIC_NULL_PTID means that we don't have any active threads, so we
-	 don't have any PID numbers the inferior will understand.  Make sure
-	 to only send forms that do not specify a PID.  */
+      /* MAGIC_NULL_PTID means that we don't have any active threads,
+	 so we don't have any TID numbers the inferior will
+	 understand.  Make sure to only send forms that do not specify
+	 a TID.  */
       if (step && siggnal != TARGET_SIGNAL_0)
 	outbuf = xstrprintf ("vCont;S%02x", siggnal);
       else if (step)
@@ -3060,31 +3103,31 @@ remote_vcont_resume (ptid_t ptid, int st
       else
 	outbuf = xstrprintf ("vCont;c");
     }
-  else if (pid == -1)
+  else if (ptid_equal (ptid, minus_one_ptid))
     {
       /* Resume all threads, with preference for INFERIOR_PTID.  */
+      int tid = ptid_get_tid (inferior_ptid);
       if (step && siggnal != TARGET_SIGNAL_0)
-	outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal,
-			     PIDGET (inferior_ptid));
+	outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal, tid);
       else if (step)
-	outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid));
+	outbuf = xstrprintf ("vCont;s:%x;c", tid);
       else if (siggnal != TARGET_SIGNAL_0)
-	outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal,
-			     PIDGET (inferior_ptid));
+	outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal, tid);
       else
 	outbuf = xstrprintf ("vCont;c");
     }
   else
     {
       /* Scheduler locking; resume only PTID.  */
+      int tid = ptid_get_tid (ptid);
       if (step && siggnal != TARGET_SIGNAL_0)
-	outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid);
+	outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, tid);
       else if (step)
-	outbuf = xstrprintf ("vCont;s:%x", pid);
+	outbuf = xstrprintf ("vCont;s:%x", tid);
       else if (siggnal != TARGET_SIGNAL_0)
-	outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid);
+	outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, tid);
       else
-	outbuf = xstrprintf ("vCont;c:%x", pid);
+	outbuf = xstrprintf ("vCont;c:%x", tid);
     }
 
   gdb_assert (outbuf && strlen (outbuf) < get_remote_packet_size ());
@@ -3108,7 +3151,6 @@ remote_resume (ptid_t ptid, int step, en
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
-  int pid = PIDGET (ptid);
 
   last_sent_signal = siggnal;
   last_sent_step = step;
@@ -3120,11 +3162,12 @@ remote_resume (ptid_t ptid, int step, en
   if (remote_vcont_resume (ptid, step, siggnal))
     goto done;
 
-  /* All other supported resume packets do use Hc, so call set_thread.  */
-  if (pid == -1)
-    set_thread (0, 0);		/* Run any thread.  */
+  /* All other supported resume packets do use Hc, so set the continue
+     thread.  */
+  if (ptid_equal (ptid, minus_one_ptid))
+    set_continue_thread (any_thread_ptid);
   else
-    set_thread (pid, 0);	/* Run this thread.  */
+    set_continue_thread (ptid);
 
   buf = rs->buf;
   if (siggnal != TARGET_SIGNAL_0)
@@ -3347,9 +3390,7 @@ remote_console_output (char *msg)
 }
 
 /* Wait until the remote machine stops, then return,
-   storing status in STATUS just as `wait' would.
-   Returns "pid", which in the case of a multi-threaded
-   remote OS, is the thread-id.  */
+   storing status in STATUS just as `wait' would.  */
 
 static ptid_t
 remote_wait (ptid_t ptid, struct target_waitstatus *status)
@@ -3357,6 +3398,7 @@ remote_wait (ptid_t ptid, struct target_
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
+  ULONGEST process_num = -1;
   ULONGEST addr;
   int solibs_changed = 0;
 
@@ -3453,7 +3495,6 @@ Packet: '%s'\n"),
 		    if (strncmp (p, "thread", p1 - p) == 0)
 		      {
 			p_temp = unpack_varlen_hex (++p1, &thread_num);
-			record_currthread (thread_num);
 			p = p_temp;
 		      }
 		    else if ((strncmp (p, "watch", p1 - p) == 0)
@@ -3575,8 +3616,12 @@ Packet: '%s'\n"),
 got_status:
   if (thread_num != -1)
     {
-      return pid_to_ptid (thread_num);
+      ptid_t ptid;
+      ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, thread_num);
+      record_currthread (ptid);
+      return ptid;
     }
+
   return inferior_ptid;
 }
 
@@ -3779,7 +3824,7 @@ remote_fetch_registers (struct regcache 
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
 
-  set_thread (PIDGET (inferior_ptid), 1);
+  set_general_thread (inferior_ptid);
 
   if (regnum >= 0)
     {
@@ -3928,7 +3973,7 @@ remote_store_registers (struct regcache 
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
 
-  set_thread (PIDGET (inferior_ptid), 1);
+  set_general_thread (inferior_ptid);
 
   if (regnum >= 0)
     {
@@ -5107,7 +5152,7 @@ extended_remote_mourn_1 (struct target_o
       /* Assume that the target has been restarted.  Set inferior_ptid
 	 so that bits of core GDB realizes there's something here, e.g.,
 	 so that the user can say "kill" again.  */
-      inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+      inferior_ptid = magic_null_ptid;
     }
   else
     {
@@ -5221,7 +5266,7 @@ extended_remote_create_inferior_1 (char 
 
   /* Now mark the inferior as running before we do anything else.  */
   attach_flag = 0;
-  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+  inferior_ptid = magic_null_ptid;
   target_mark_running (&extended_remote_ops);
 
   /* Get updated offsets, if the stub uses qOffsets.  */
@@ -6143,7 +6188,7 @@ threadset_test_cmd (char *cmd, int tty)
   int sample_thread = SAMPLE_THREAD;
 
   printf_filtered (_("Remote threadset test\n"));
-  set_thread (sample_thread, 1);
+  set_general_thread (sample_thread);
 }
 
 
@@ -6151,8 +6196,10 @@ static void
 threadalive_test (char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
+  int pid = ptid_get_pid (inferior_ptid);
+  ptid_t ptid = ptid_build (pid, 0, sample_thread);
 
-  if (remote_thread_alive (pid_to_ptid (sample_thread)))
+  if (remote_thread_alive (ptid))
     printf_filtered ("PASS: Thread alive test\n");
   else
     printf_filtered ("FAIL: Thread alive test\n");
@@ -6265,10 +6312,21 @@ Fetch and print the remote list of threa
 static char *
 remote_pid_to_str (ptid_t ptid)
 {
-  static char buf[32];
+  static char buf[64];
 
-  xsnprintf (buf, sizeof buf, "Thread %d", ptid_get_pid (ptid));
-  return buf;
+  if (ptid_equal (magic_null_ptid, ptid))
+    {
+      xsnprintf (buf, sizeof buf, "Thread <main>");
+      return buf;
+    }
+  else if (ptid_get_tid (ptid) != 0)
+    {
+      xsnprintf (buf, sizeof buf, "Thread %ld",
+		 ptid_get_tid (ptid));
+      return buf;
+    }
+
+  return normal_pid_to_str (ptid);
 }
 
 /* Get the address of the thread local variable in OBJFILE which is
@@ -6285,7 +6343,7 @@ remote_get_thread_local_address (ptid_t 
 
       strcpy (p, "qGetTLSAddr:");
       p += strlen (p);
-      p += hexnumstr (p, PIDGET (ptid));
+      p += hexnumstr (p, ptid_get_tid (ptid));
       *p++ = ',';
       p += hexnumstr (p, offset);
       *p++ = ',';
@@ -7479,4 +7537,10 @@ Tells gdb whether to control the remote 
 
   /* Eventually initialize fileio.  See fileio.c */
   initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
+
+  /* Take advantage of the fact that the LWP field is not used, to tag
+     special ptids with it set to != 0.  */
+  magic_null_ptid = ptid_build (0, 1, -1);
+  not_sent_ptid = ptid_build (0, 1, -2);
+  any_thread_ptid = ptid_build (0, 1, 0);
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: make the remote target store thread ids in ptid_t.tid
  2008-06-25 23:11 make the remote target store thread ids in ptid_t.tid Pedro Alves
@ 2008-06-26  3:21 ` Daniel Jacobowitz
  2008-06-27 12:33   ` Pedro Alves
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-06-26  3:21 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Wed, Jun 25, 2008 at 11:51:59PM +0100, Pedro Alves wrote:
> I've tested this extensivelly by talking to a native gdbserver,
> and native gdbserver with vCont disabled, and then also with a
> gdbserver with vCont and all thread related packets and fields
> disabled, to simulate old stubs and stubs that don't support
> threads at all.

These sound useful for testing.  Any interest in making them command
line options for gdbserver?

> 2008-06-25  Pedro Alves  <pedro@codesourcery.com>
> 
> 	Use ptid_t.tid to store thread ids instead of ptid_t.pid.
> 
> 	* remote.c (magic_null_ptid, not_sent_ptid, any_thread_ptid): New
> 	globals.
> 	(general_thread, continue_thread): Change type to ptid_t.
> 	(record_currthread): Take a ptid_t parameter instead of an
> 	integer.
> 	(MAGIC_NULL_PID): Delete.
> 	(set_thread): Take a ptid_t parameter and adjust.
> 	(set_general_thread, set_continue_thread): New.
> 	(remote_thread_alive, remote_newthread_step)
> 	(remote_current_thread, remote_find_new_threads)
> 	(remote_threads_info, remote_start_remote, remote_vcont_resume)
> 	(remote_resume_1, remote_wait, extended_remote_create_inferior_1)
> 	(threadalive_test, remote_pid_to_str)
> 	(remote_get_thread_local_address): Adjust.
> 	(_initialize_remote): Initialize magic_null_ptid, not_sent_ptid
> 	and any_thread_ptid.

Looks OK to me.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: make the remote target store thread ids in ptid_t.tid
  2008-06-26  3:21 ` Daniel Jacobowitz
@ 2008-06-27 12:33   ` Pedro Alves
  2008-06-27 13:26     ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Pedro Alves @ 2008-06-27 12:33 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2540 bytes --]

> > 2008-06-25  Pedro Alves  <pedro@codesourcery.com>
> >
> > 	Use ptid_t.tid to store thread ids instead of ptid_t.pid.
> >
> > 	* remote.c (magic_null_ptid, not_sent_ptid, any_thread_ptid): New
> > 	globals.
> > 	(general_thread, continue_thread): Change type to ptid_t.
> > 	(record_currthread): Take a ptid_t parameter instead of an
> > 	integer.
> > 	(MAGIC_NULL_PID): Delete.
> > 	(set_thread): Take a ptid_t parameter and adjust.
> > 	(set_general_thread, set_continue_thread): New.
> > 	(remote_thread_alive, remote_newthread_step)
> > 	(remote_current_thread, remote_find_new_threads)
> > 	(remote_threads_info, remote_start_remote, remote_vcont_resume)
> > 	(remote_resume_1, remote_wait, extended_remote_create_inferior_1)
> > 	(threadalive_test, remote_pid_to_str)
> > 	(remote_get_thread_local_address): Adjust.
> > 	(_initialize_remote): Initialize magic_null_ptid, not_sent_ptid
> > 	and any_thread_ptid.
>
> Looks OK to me.

Thanks, I've checked this in.

A Thursday 26 June 2008 03:22:32, Daniel Jacobowitz wrote:
> On Wed, Jun 25, 2008 at 11:51:59PM +0100, Pedro Alves wrote:
> > I've tested this extensivelly by talking to a native gdbserver,
> > and native gdbserver with vCont disabled, and then also with a
> > gdbserver with vCont and all thread related packets and fields
> > disabled, to simulate old stubs and stubs that don't support
> > threads at all.
>
> These sound useful for testing.  Any interest in making them command
> line options for gdbserver?

Sure, something like this?

I don't think we should advertize the options in --help, as
this isn't something we want users to be poking with.

>./gdbserver  --disable-packet
Disableable packets:
  vCont         All vCont packets
  qC            Querying the current thread
  qfThreadInfo  Thread listing
  Tthread       Passing the thread specifier in the T stop reply packet
  threads       All of the above

>./gdbserver  --disable-packet=boo
Don't know how to disable "boo".

Disableable packets:
  vCont         All vCont packets
  qC            Querying the current thread
  qfThreadInfo  Thread listing
  Tthread       Passing the thread specifier in the T stop reply packet
  threads       All of the above

>./gdbserver  --disable-packet=vCont :9999 ./gdbserver
Process ./gdbserver created; pid = 20022
Listening on port 9999


You can then put the extra options in the board file, say, in
the standard native gdbserver board file, it could be:
set_board_info 
gdb_server_prog "../gdbserver/gdbserver  --disable-packet=threads"



-- 
Pedro Alves

[-- Attachment #2: gdbserver_disable_packets.diff --]
[-- Type: text/x-diff, Size: 6958 bytes --]

2008-06-27  Pedro Alves  <pedro@codesourcery.com>

	* remote-utils.c (prepare_resume_reply): If requested, don't
	output "thread:TID" in the T stop reply.

	* server.c (disable_packet_vCont, disable_packet_Tthread)
	(disable_packet_qC, disable_packet_qfThreadInfo): New globals.
	(handle_query): If requested, disable support for qC, qfThreadInfo
	and qsThreadInfo.
	(handle_v_requests): If requested, disable support for vCont.
	(gdbserver_show_disableable): New.
	(main): Handle --disable-packet and --disable-packet=LIST.

	* server.h (disable_packet_vCont, disable_packet_Tthread)
	(disable_packet_qC, disable_packet_qfThreadInfo): Declare.

---
 gdb/gdbserver/remote-utils.c |    2 
 gdb/gdbserver/server.c       |  118 +++++++++++++++++++++++++++++++++----------
 gdb/gdbserver/server.h       |    5 +
 3 files changed, 98 insertions(+), 27 deletions(-)

Index: src/gdb/gdbserver/remote-utils.c
===================================================================
--- src.orig/gdb/gdbserver/remote-utils.c	2008-06-27 12:22:09.000000000 +0100
+++ src/gdb/gdbserver/remote-utils.c	2008-06-27 12:26:42.000000000 +0100
@@ -944,7 +944,7 @@ prepare_resume_reply (char *buf, char st
 	 Since thread support relies on qSymbol support anyway, assume GDB can handle
 	 threads.  */
 
-      if (using_threads)
+      if (using_threads && !disable_packet_Tthread)
 	{
 	  unsigned int gdb_id_from_wait;
 
Index: src/gdb/gdbserver/server.c
===================================================================
--- src.orig/gdb/gdbserver/server.c	2008-06-27 12:22:09.000000000 +0100
+++ src/gdb/gdbserver/server.c	2008-06-27 12:27:15.000000000 +0100
@@ -67,6 +67,14 @@ int terminal_fd;
 /* TERMINAL_FD's original foreground group.  */
 pid_t old_foreground_pgrp;
 
+/* Set if you want to disable optional thread related packets support
+   in gdbserver, for the sake of testing GDB against stubs that don't
+   support them.  */
+int disable_packet_vCont;
+int disable_packet_Tthread;
+int disable_packet_qC;
+int disable_packet_qfThreadInfo;
+
 /* Hand back terminal ownership to the original foreground group.  */
 
 static void
@@ -475,12 +483,12 @@ handle_query (char *own_buf, int packet_
   static struct inferior_list_entry *thread_ptr;
 
   /* Reply the current thread id.  */
-  if (strcmp ("qC", own_buf) == 0)
+  if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
     {
       require_running (own_buf);
       thread_ptr = all_threads.head;
       sprintf (own_buf, "QC%x",
-	thread_to_gdb_id ((struct thread_info *)thread_ptr));
+	       thread_to_gdb_id ((struct thread_info *)thread_ptr));
       return;
     }
 
@@ -493,28 +501,31 @@ handle_query (char *own_buf, int packet_
       return;
     }
 
-  if (strcmp ("qfThreadInfo", own_buf) == 0)
+  if (!disable_packet_qfThreadInfo)
     {
-      require_running (own_buf);
-      thread_ptr = all_threads.head;
-      sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
-      thread_ptr = thread_ptr->next;
-      return;
-    }
-
-  if (strcmp ("qsThreadInfo", own_buf) == 0)
-    {
-      require_running (own_buf);
-      if (thread_ptr != NULL)
+      if (strcmp ("qfThreadInfo", own_buf) == 0)
 	{
+	  require_running (own_buf);
+	  thread_ptr = all_threads.head;
 	  sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
 	  thread_ptr = thread_ptr->next;
 	  return;
 	}
-      else
+
+      if (strcmp ("qsThreadInfo", own_buf) == 0)
 	{
-	  sprintf (own_buf, "l");
-	  return;
+	  require_running (own_buf);
+	  if (thread_ptr != NULL)
+	    {
+	      sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
+	      thread_ptr = thread_ptr->next;
+	      return;
+	    }
+	  else
+	    {
+	      sprintf (own_buf, "l");
+	      return;
+	    }
 	}
     }
 
@@ -1098,17 +1109,20 @@ void
 handle_v_requests (char *own_buf, char *status, int *signal,
 		   int packet_len, int *new_packet_len)
 {
-  if (strncmp (own_buf, "vCont;", 6) == 0)
+  if (!disable_packet_vCont)
     {
-      require_running (own_buf);
-      handle_v_cont (own_buf, status, signal);
-      return;
-    }
+      if (strncmp (own_buf, "vCont;", 6) == 0)
+	{
+	  require_running (own_buf);
+	  handle_v_cont (own_buf, status, signal);
+	  return;
+	}
 
-  if (strncmp (own_buf, "vCont?", 6) == 0)
-    {
-      strcpy (own_buf, "vCont;c;C;s;S");
-      return;
+      if (strncmp (own_buf, "vCont?", 6) == 0)
+	{
+	  strcpy (own_buf, "vCont;c;C;s;S");
+	  return;
+	}
     }
 
   if (strncmp (own_buf, "vFile:", 6) == 0
@@ -1203,6 +1217,18 @@ gdbserver_usage (FILE *stream)
     fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
 }
 
+static void
+gdbserver_show_disableable (FILE *stream)
+{
+  fprintf (stream, "Disableable packets:\n"
+	   "  vCont       \tAll vCont packets\n"
+	   "  qC          \tQuerying the current thread\n"
+	   "  qfThreadInfo\tThread listing\n"
+	   "  Tthread     \tPassing the thread specifier in the T stop reply packet\n"
+	   "  threads     \tAll of the above\n");
+}
+
+
 #undef require_running
 #define require_running(BUF)			\
   if (!target_running ())			\
@@ -1263,6 +1289,46 @@ main (int argc, char *argv[])
 	}
       else if (strcmp (*next_arg, "--debug") == 0)
 	debug_threads = 1;
+      else if (strcmp (*next_arg, "--disable-packet") == 0)
+	{
+	  gdbserver_show_disableable (stdout);
+	  exit (1);
+	}
+      else if (strncmp (*next_arg,
+			"--disable-packet=",
+			sizeof ("--disable-packet=") - 1) == 0)
+	{
+	  char *packets, *tok;
+
+	  packets = *next_arg += sizeof ("--disable-packet=") - 1;
+	  for (tok = strtok (packets, ",");
+	       tok != NULL;
+	       tok = strtok (NULL, ","))
+	    {
+	      if (strcmp ("vCont", tok) == 0)
+		disable_packet_vCont = 1;
+	      else if (strcmp ("Tthread", tok) == 0)
+		disable_packet_Tthread = 1;
+	      else if (strcmp ("qC", tok) == 0)
+		disable_packet_qC = 1;
+	      else if (strcmp ("qfThreadInfo", tok) == 0)
+		disable_packet_qfThreadInfo = 1;
+	      else if (strcmp ("threads", tok) == 0)
+		{
+		  disable_packet_vCont = 1;
+		  disable_packet_Tthread = 1;
+		  disable_packet_qC = 1;
+		  disable_packet_qfThreadInfo = 1;
+		}
+	      else
+		{
+		  fprintf (stderr, "Don't know how to disable \"%s\".\n\n",
+			   tok);
+		  gdbserver_show_disableable (stderr);
+		  exit (1);
+		}
+	    }
+	}
       else
 	{
 	  fprintf (stderr, "Unknown argument: %s\n", *next_arg);
Index: src/gdb/gdbserver/server.h
===================================================================
--- src.orig/gdb/gdbserver/server.h	2008-06-27 12:22:09.000000000 +0100
+++ src/gdb/gdbserver/server.h	2008-06-27 12:26:42.000000000 +0100
@@ -156,6 +156,11 @@ extern int pass_signals[];
 
 extern jmp_buf toplevel;
 
+extern int disable_packet_vCont;
+extern int disable_packet_Tthread;
+extern int disable_packet_qC;
+extern int disable_packet_qfThreadInfo;
+
 /* Functions from hostio.c.  */
 extern int handle_vFile (char *, int, int *);
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: make the remote target store thread ids in ptid_t.tid
  2008-06-27 12:33   ` Pedro Alves
@ 2008-06-27 13:26     ` Daniel Jacobowitz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-06-27 13:26 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Fri, Jun 27, 2008 at 12:59:22PM +0100, Pedro Alves wrote:
> Sure, something like this?

Yeah, this looks fine.  OK.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-06-27 12:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-25 23:11 make the remote target store thread ids in ptid_t.tid Pedro Alves
2008-06-26  3:21 ` Daniel Jacobowitz
2008-06-27 12:33   ` Pedro Alves
2008-06-27 13:26     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox