[PATCHv9,11/14] gdb: create new is_thread_id helper function

Message ID 949fcb519598b2c884d15158d3490f805f51262f.1709651994.git.aburgess@redhat.com
State New
Headers
Series thread-specific breakpoints in just some inferiors |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Andrew Burgess March 5, 2024, 3:21 p.m. UTC
  This is a refactoring commit that splits the existing parse_thread_id
function into two parts, and then adds a new is_thread_id function.

The core of parse_thread_id is split into parse_thread_id_1, which is
responsible for actually parsing a thread-id.  Then parse_thread_id is
responsible for taking a parsed thread-id and validating that it
references an actually existing inferior thread.

The new is_thread_id function also uses parse_thread_id_1, but doesn't
actually check that the inferior thread exists, instead, this new
function simply checks that a string looks like a thread-id.

This commit does not add a use for is_thread_id, this will be added in
the next commit.

This is a refactoring commit, there should be no user visible changes
after this commit.
---
 gdb/tid-parse.c | 82 +++++++++++++++++++++++++++++++++++++------------
 gdb/tid-parse.h |  8 +++++
 2 files changed, 70 insertions(+), 20 deletions(-)
  

Patch

diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c
index aa1480d7cf0..7f85b94eba4 100644
--- a/gdb/tid-parse.c
+++ b/gdb/tid-parse.c
@@ -48,40 +48,43 @@  get_positive_number_trailer (const char **pp, int trailer, const char *string)
   return num;
 }
 
-/* See tid-parse.h.  */
+/* Parse TIDSTR as a per-inferior thread ID, in either INF_NUM.THR_NUM
+   or THR_NUM form, and return a pair, the first item of the pair is
+   INF_NUM and the second item is THR_NUM.
 
-struct thread_info *
-parse_thread_id (const char *tidstr, const char **end)
+   If TIDSTR does not include an INF_NUM component, then the first item in
+   the pair will be 0 (which is an invalid inferior number), this indicates
+   that TIDSTR references the current inferior.
+
+   This function does not validate the INF_NUM and THR_NUM are actually
+   valid numbers, that is, they might reference inferiors or threads that
+   don't actually exist; this function just splits the string into its
+   component parts.
+
+   If there is an error parsing TIDSTR then this function will raise an
+   exception.  */
+
+static std::pair<int, int>
+parse_thread_id_1 (const char *tidstr, const char **end)
 {
   const char *number = tidstr;
   const char *dot, *p1;
-  struct inferior *inf;
-  int thr_num;
-  int explicit_inf_id = 0;
+  int thr_num, inf_num;
 
   dot = strchr (number, '.');
 
   if (dot != NULL)
     {
       /* Parse number to the left of the dot.  */
-      int inf_num;
-
       p1 = number;
       inf_num = get_positive_number_trailer (&p1, '.', number);
       if (inf_num == 0)
 	invalid_thread_id_error (number);
-
-      inf = find_inferior_id (inf_num);
-      if (inf == NULL)
-	error (_("No inferior number '%d'"), inf_num);
-
-      explicit_inf_id = 1;
       p1 = dot + 1;
     }
   else
     {
-      inf = current_inferior ();
-
+      inf_num = 0;
       p1 = number;
     }
 
@@ -89,6 +92,32 @@  parse_thread_id (const char *tidstr, const char **end)
   if (thr_num == 0)
     invalid_thread_id_error (number);
 
+  if (end != nullptr)
+    *end = p1;
+
+  return { inf_num, thr_num };
+}
+
+/* See tid-parse.h.  */
+
+struct thread_info *
+parse_thread_id (const char *tidstr, const char **end)
+{
+  const auto [inf_num, thr_num] = parse_thread_id_1 (tidstr, end);
+
+  inferior *inf;
+  bool explicit_inf_id = false;
+
+  if (inf_num != 0)
+    {
+      inf = find_inferior_id (inf_num);
+      if (inf == nullptr)
+	error (_("No inferior number '%d'"), inf_num);
+      explicit_inf_id = true;
+    }
+  else
+    inf = current_inferior ();
+
   thread_info *tp = nullptr;
   for (thread_info *it : inf->threads ())
     if (it->per_inf_num == thr_num)
@@ -97,7 +126,7 @@  parse_thread_id (const char *tidstr, const char **end)
 	break;
       }
 
-  if (tp == NULL)
+  if (tp == nullptr)
     {
       if (show_inferior_qualified_tids () || explicit_inf_id)
 	error (_("Unknown thread %d.%d."), inf->num, thr_num);
@@ -105,14 +134,27 @@  parse_thread_id (const char *tidstr, const char **end)
 	error (_("Unknown thread %d."), thr_num);
     }
 
-  if (end != NULL)
-    *end = p1;
-
   return tp;
 }
 
 /* See tid-parse.h.  */
 
+bool
+is_thread_id (const char *tidstr, const char **end)
+{
+  try
+    {
+      (void) parse_thread_id_1 (tidstr, end);
+      return true;
+    }
+  catch (const gdb_exception_error &)
+    {
+      return false;
+    }
+}
+
+/* See tid-parse.h.  */
+
 tid_range_parser::tid_range_parser (const char *tidlist,
 				    int default_inferior)
 {
diff --git a/gdb/tid-parse.h b/gdb/tid-parse.h
index b7bd920f48a..bba5ae5118c 100644
--- a/gdb/tid-parse.h
+++ b/gdb/tid-parse.h
@@ -36,6 +36,14 @@  extern void ATTRIBUTE_NORETURN invalid_thread_id_error (const char *string);
    thrown.  */
 struct thread_info *parse_thread_id (const char *tidstr, const char **end);
 
+/* Return true if TIDSTR is pointing to a string that looks like a
+   thread-id.  This doesn't mean that TIDSTR identifies a valid thread, but
+   the string does at least look like a valid thread-id.  If END is not
+   NULL, parse_thread_id stores the address of the first character after
+   the thread-id into *END.  */
+
+bool is_thread_id (const char *tidstr, const char **end);
+
 /* Parse a thread ID or a thread range list.
 
    A range will be of the form