public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Correctly handle non-C-style arrays in c_get_string
@ 2019-05-08 16:24 Tom Tromey
  0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2019-05-08 16:24 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=80e55b132940813fa454da2592a31db6c8af85f1

commit 80e55b132940813fa454da2592a31db6c8af85f1
Author: Tom Tromey <tromey@adacore.com>
Date:   Thu Apr 25 12:14:58 2019 -0600

    Correctly handle non-C-style arrays in c_get_string
    
    A user here noticed that the Python Value.string method did not work
    for Ada arrays.  I tracked this down to an oddity in value_as_address
    -- namely, it calls coerce_array, but that function will not force
    array coercion when the language has c_style_arrays=false, as Ada
    does.
    
    This patch fixes the problem by changing c_get_string so that arrays
    take the "in GDB's memory" branch.  The actual patch is somewhat more
    complicated than you might think, because the caller can request more
    array elements than the type allows.  This is normal when the type is
    using the C struct hack.
    
    Tested on x86-64 Fedora 29.
    
    gdb/ChangeLog
    2019-05-08  Tom Tromey  <tromey@adacore.com>
    
    	* c-lang.c (c_get_string): Handle non-C-style arrays.
    
    gdb/testsuite/ChangeLog
    2019-05-08  Tom Tromey  <tromey@adacore.com>
    
    	* gdb.python/py-value.exp (test_value_in_inferior): Add Ada test.

Diff:
---
 gdb/ChangeLog                         |  4 ++++
 gdb/c-lang.c                          | 31 +++++++++++++++++++++++++++----
 gdb/testsuite/ChangeLog               |  4 ++++
 gdb/testsuite/gdb.python/py-value.exp | 13 +++++++++++++
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 93641a0..2d723cb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,9 @@
 2019-05-08  Tom Tromey  <tromey@adacore.com>
 
+	* c-lang.c (c_get_string): Handle non-C-style arrays.
+
+2019-05-08  Tom Tromey  <tromey@adacore.com>
+
 	* typeprint.c (print_offset_data::update): Print the bit offset,
 	not the number of bits remaining.
 
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index aeffefa..5bb771b 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -279,10 +279,21 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
   /* If the string lives in GDB's memory instead of the inferior's,
      then we just need to copy it to BUFFER.  Also, since such strings
      are arrays with known size, FETCHLIMIT will hold the size of the
-     array.  */
+     array.
+
+     An array is assumed to live in GDB's memory, so we take this path
+     here.
+
+     However, it's possible for the caller to request more array
+     elements than apparently exist -- this can happen when using the
+     C struct hack.  So, only do this if either no length was
+     specified, or the length is within the existing bounds.  This
+     avoids running off the end of the value's contents.  */
   if ((VALUE_LVAL (value) == not_lval
-       || VALUE_LVAL (value) == lval_internalvar)
-      && fetchlimit != UINT_MAX)
+       || VALUE_LVAL (value) == lval_internalvar
+       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+      && fetchlimit != UINT_MAX
+      && (*length < 0 || *length <= fetchlimit))
     {
       int i;
       const gdb_byte *contents = value_contents (value);
@@ -306,7 +317,19 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
     }
   else
     {
-      CORE_ADDR addr = value_as_address (value);
+      /* value_as_address does not return an address for an array when
+	 c_style_arrays is false, so we handle that specially
+	 here.  */
+      CORE_ADDR addr;
+      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+	{
+	  if (VALUE_LVAL (value) != lval_memory)
+	    error (_("Attempt to take address of value "
+		     "not located in memory."));
+	  addr = value_address (value);
+	}
+      else
+	addr = value_as_address (value);
 
       /* Prior to the fix for PR 16196 read_string would ignore fetchlimit
 	 if length > 0.  The old "broken" behaviour is the behaviour we want:
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6b51db8..817576c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2019-05-08  Tom Tromey  <tromey@adacore.com>
 
+	* gdb.python/py-value.exp (test_value_in_inferior): Add Ada test.
+
+2019-05-08  Tom Tromey  <tromey@adacore.com>
+
 	* gdb.base/ptype-offsets.exp: Update tests.
 
 2019-05-08  Tom Tromey  <tromey@adacore.com>
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index b3d90b5..51edfa3 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -315,6 +315,13 @@ proc test_value_in_inferior {} {
   gdb_test "python print (\"---\"+st.string (length = 0)+\"---\")" "------" "test string (length = 0) is empty"
   gdb_test "python print (len(st.string (length = 0)))" "0" "test length is 0"
 
+  # We choose Ada here to test a language where c_style_arrays is
+  # false.
+  gdb_test "set lang ada" \
+      "Warning: the current language does not match this frame."
+  gdb_test "python print (st.string ())"  "divide et impera"  \
+      "Test string with no length in ada"
+  gdb_test_no_output "set lang auto"
 
   # Fetch a string that has embedded nulls.
   gdb_test "print nullst" "\"divide\\\\000et\\\\000impera\".*"
@@ -330,6 +337,12 @@ proc test_value_in_inferior {} {
   gdb_py_test_silent_cmd "python xstr = gdb.parse_and_eval('xstr')" "get xstr" 1
   gdb_test "python print(xstr\['text'\].string (length = xstr\['length'\]))" "x{100}" \
     "read string beyond declared size"
+
+  # However it shouldn't be possible to fetch past the end of a
+  # non-memory value.
+  gdb_py_test_silent_cmd "python str = '\"str\"'" "set up str variable" 1
+  gdb_test "python print (gdb.parse_and_eval (str).string (length = 10))" \
+      "gdb.error: Attempt to take address of value not located in memory.\r\nError while executing Python code."
 }
 
 proc test_inferior_function_call {} {


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-05-08 16:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-08 16:24 [binutils-gdb] Correctly handle non-C-style arrays in c_get_string Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).