[v2,2/8] Remove static buffer from ada_decode

Message ID 20190518210010.27697-3-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey May 18, 2019, 9 p.m. UTC
  ada_decode has a static buffer, which means it is not thread-safe.
This patch removes the buffer and adds a parameter so that the storage
can be managed by the caller.

gdb/ChangeLog
2019-05-18  Tom Tromey  <tom@tromey.com>

	* ada-varobj.c (ada_varobj_describe_simple_array_child): Update.
	* ada-lang.h (ada_decode): Add "storage" parameter.
	* ada-lang.c (ada_decode): Add "storage" parameter.
	(ada_decode_symbol, ada_la_decode, ada_sniff_from_mangled_name)
	(is_valid_name_for_wild_match, name_matches_regex)
	(ada_add_global_exceptions): Update.
	* ada-exp.y (write_object_renaming): Update.
---
 gdb/ChangeLog    | 10 +++++++++
 gdb/ada-exp.y    |  6 +++++-
 gdb/ada-lang.c   | 55 ++++++++++++++++++++++++++++++------------------
 gdb/ada-lang.h   |  3 ++-
 gdb/ada-varobj.c |  3 ++-
 5 files changed, 54 insertions(+), 23 deletions(-)
  

Patch

diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 92461dbcb69..279d8db61f7 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -816,7 +816,11 @@  write_object_renaming (struct parser_state *par_state,
 				 renamed_entity_len);
   ada_lookup_encoded_symbol (name, orig_left_context, VAR_DOMAIN, &sym_info);
   if (sym_info.symbol == NULL)
-    error (_("Could not find renamed variable: %s"), ada_decode (name));
+    {
+      gdb::unique_xmalloc_ptr<char> storage;
+      error (_("Could not find renamed variable: %s"),
+	     ada_decode (name, &storage));
+    }
   else if (SYMBOL_CLASS (sym_info.symbol) == LOC_TYPEDEF)
     /* We have a renaming of an old-style renaming symbol.  Don't
        trust the block information.  */
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 23197f60340..4e6b1965557 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -1134,22 +1134,18 @@  ada_remove_Xbn_suffix (const char *encoded, int *len)
 
 /* If ENCODED follows the GNAT entity encoding conventions, then return
    the decoded form of ENCODED.  Otherwise, return "<%s>" where "%s" is
-   replaced by ENCODED.
-
-   The resulting string is valid until the next call of ada_decode.
-   If the string is unchanged by decoding, the original string pointer
-   is returned.  */
+   replaced by ENCODED.  */
 
 const char *
-ada_decode (const char *encoded)
+ada_decode (const char *encoded, gdb::unique_xmalloc_ptr<char> *storage)
 {
   int i, j;
   int len0;
   const char *p;
   char *decoded;
   int at_start_name;
-  static char *decoding_buffer = NULL;
-  static size_t decoding_buffer_size = 0;
+  char *decoding_buffer = NULL;
+  size_t decoding_buffer_size = 0;
 
   /* With function descriptors on PPC64, the value of a symbol named
      ".FN", if it exists, is the entry point of the function "FN".  */
@@ -1377,9 +1373,15 @@  ada_decode (const char *encoded)
       goto Suppress;
 
   if (strcmp (decoded, encoded) == 0)
-    return encoded;
+    {
+      xfree (decoding_buffer);
+      return encoded;
+    }
   else
-    return decoded;
+    {
+      storage->reset (decoded);
+      return decoded;
+    }
 
 Suppress:
   GROW_VECT (decoding_buffer, decoding_buffer_size, strlen (encoded) + 3);
@@ -1388,8 +1390,8 @@  Suppress:
     strcpy (decoded, encoded);
   else
     xsnprintf (decoded, decoding_buffer_size, "<%s>", encoded);
+  storage->reset (decoded);
   return decoded;
-
 }
 
 /* Table for keeping permanent unique copies of decoded names.  Once
@@ -1418,7 +1420,8 @@  ada_decode_symbol (const struct general_symbol_info *arg)
 
   if (!gsymbol->ada_mangled)
     {
-      const char *decoded = ada_decode (gsymbol->name);
+      gdb::unique_xmalloc_ptr<char> storage;
+      const char *decoded = ada_decode (gsymbol->name, &storage);
       struct obstack *obstack = gsymbol->language_specific.obstack;
 
       gsymbol->ada_mangled = 1;
@@ -1448,7 +1451,8 @@  ada_decode_symbol (const struct general_symbol_info *arg)
 static char *
 ada_la_decode (const char *encoded, int options)
 {
-  return xstrdup (ada_decode (encoded));
+  gdb::unique_xmalloc_ptr<char> storage;
+  return xstrdup (ada_decode (encoded, &storage));
 }
 
 /* Implement la_sniff_from_mangled_name for Ada.  */
@@ -1456,7 +1460,8 @@  ada_la_decode (const char *encoded, int options)
 static int
 ada_sniff_from_mangled_name (const char *mangled, char **out)
 {
-  const char *demangled = ada_decode (mangled);
+  gdb::unique_xmalloc_ptr<char> storage;
+  const char *demangled = ada_decode (mangled, &storage);
 
   *out = NULL;
 
@@ -6091,7 +6096,8 @@  is_name_suffix (const char *str)
 static int
 is_valid_name_for_wild_match (const char *name0)
 {
-  const char *decoded_name = ada_decode (name0);
+  gdb::unique_xmalloc_ptr<char> storage;
+  const char *decoded_name = ada_decode (name0, &storage);
   int i;
 
   /* If the decoded name starts with an angle bracket, it means that
@@ -6339,8 +6345,9 @@  ada_lookup_name_info::matches
          is not a suitable completion.  */
       const char *sym_name_copy = sym_name;
       bool has_angle_bracket;
+      gdb::unique_xmalloc_ptr<char> storage;
 
-      sym_name = ada_decode (sym_name);
+      sym_name = ada_decode (sym_name, &storage);
       has_angle_bracket = (sym_name[0] == '<');
       match = (has_angle_bracket == m_verbatim_p);
       sym_name = sym_name_copy;
@@ -6362,12 +6369,14 @@  ada_lookup_name_info::matches
 
   /* Second: Try wild matching...  */
 
+  gdb::unique_xmalloc_ptr<char> sym_name_storage;
   if (!match && m_wild_match_p)
     {
       /* Since we are doing wild matching, this means that TEXT
          may represent an unqualified symbol name.  We therefore must
          also compare TEXT against the unqualified name of the symbol.  */
-      sym_name = ada_unqualified_name (ada_decode (sym_name));
+      sym_name = ada_unqualified_name (ada_decode (sym_name,
+						   &sym_name_storage));
 
       if (strncmp (sym_name, text, text_len) == 0)
 	match = true;
@@ -6383,7 +6392,10 @@  ada_lookup_name_info::matches
       std::string &match_str = comp_match_res->match.storage ();
 
       if (!m_encoded_p)
-	match_str = ada_decode (sym_name);
+	{
+	  gdb::unique_xmalloc_ptr<char> storage;
+	  match_str = ada_decode (sym_name, &storage);
+	}
       else
 	{
 	  if (m_verbatim_p)
@@ -13575,8 +13587,9 @@  ada_add_exceptions_from_frame (compiled_regex *preg,
 static bool
 name_matches_regex (const char *name, compiled_regex *preg)
 {
+  gdb::unique_xmalloc_ptr<char> storage;
   return (preg == NULL
-	  || preg->exec (ada_decode (name), 0, NULL, 0) == 0);
+	  || preg->exec (ada_decode (name, &storage), 0, NULL, 0) == 0);
 }
 
 /* Add all exceptions defined globally whose name name match
@@ -13609,7 +13622,9 @@  ada_add_global_exceptions (compiled_regex *preg,
 			   lookup_name_info::match_any (),
 			   [&] (const char *search_name)
 			   {
-			     const char *decoded = ada_decode (search_name);
+			     gdb::unique_xmalloc_ptr<char> storage;
+			     const char *decoded = ada_decode (search_name,
+							       &storage);
 			     return name_matches_regex (decoded, preg);
 			   },
 			   NULL,
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 52d597e04c1..4bcca1f9de3 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -227,7 +227,8 @@  extern struct type *ada_get_decoded_type (struct type *type);
 
 extern const char *ada_decode_symbol (const struct general_symbol_info *);
 
-extern const char *ada_decode (const char*);
+extern const char *ada_decode (const char *,
+			       gdb::unique_xmalloc_ptr<char> *storage);
 
 extern enum language ada_update_initial_language (enum language);
 
diff --git a/gdb/ada-varobj.c b/gdb/ada-varobj.c
index a4d553d3786..29a4c86cc5f 100644
--- a/gdb/ada-varobj.c
+++ b/gdb/ada-varobj.c
@@ -624,6 +624,7 @@  ada_varobj_describe_simple_array_child (struct value *parent_value,
 	 of the array index type when such type qualification is
 	 needed.  */
       const char *index_type_name = NULL;
+      gdb::unique_xmalloc_ptr<char> storage;
 
       /* If the index type is a range type, find the base type.  */
       while (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
@@ -634,7 +635,7 @@  ada_varobj_describe_simple_array_child (struct value *parent_value,
 	{
 	  index_type_name = ada_type_name (index_type);
 	  if (index_type_name)
-	    index_type_name = ada_decode (index_type_name);
+	    index_type_name = ada_decode (index_type_name, &storage);
 	}
 
       if (index_type_name != NULL)