This is the mail archive of the gdb-cvs@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]

[binutils-gdb] gdb/dwarf2read: Minimal handling of non-constant struct sizes.


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

commit 155bfbd30aacd4e01a9ac8ca8032d804ed7ece47
Author: Joel Brobecker <brobecker@adacore.com>
Date:   Mon Nov 23 09:44:16 2015 -0800

    gdb/dwarf2read: Minimal handling of non-constant struct sizes.
    
    Using the gdb.ada/var_rec_arr.exp test, where the program declares
    an array of variant records...
    
       type Record_Type (I : Small_Type := 0) is record
          S : String (1 .. I);
       end record;
       type Array_Type is array (Integer range <>) of Record_Type;
    
    ... and then a variable A1 of type Array_Type, the following command
    ocassionally trigger an internal error trying to allocate more memory
    than we have left:
    
        (gdb) ptype a1(1)
        [...]/utils.c:1089: internal-error: virtual memory exhausted.
        A problem internal to GDB has been detected,
        [...]
    
    What happens is that recent versions of GNAT are able to generate
    DWARF expressions for type Record_Type, and therefore the record's
    DW_AT_byte_size is not a constant, which unfortunately breaks
    an assumption made by dwarf2read.c:read_structure_type when it does:
    
       attr = dwarf2_attr (die, DW_AT_byte_size, cu);
       if (attr)
         {
           TYPE_LENGTH (type) = DW_UNSND (attr);
         }
    
    As a result of this, when ada_evaluate_subexp tries to create
    a value_zero for a1(1) while processing the OP_FUNCALL operator
    as part of evaluating the subscripting operation in no-side-effect
    mode, we try to allocate a value with a bogus size, potentially
    triggering the out-of-memory internal error.
    
    This patch avoids this issue by setting the length to zero in
    this case.  Until we decide to start supporting dynamic type
    lengths in GDB's type struct, and it's not clear yet that
    this is worth the effort (see added comment), that's probably
    the best we can do.
    
    gdb/ChangeLog:
    
            * dwarf2read.c (read_structure_type): Set the type's length
            to zero if it has a DW_AT_byte_size attribute which is not
            a constant.
    
    gdb/testsuite/ChangeLog:
    
            * testsuite/gdb.ada/var_rec_arr.exp: Add "ptype a1(1)" test.

Diff:
---
 gdb/ChangeLog                         |  6 ++++++
 gdb/dwarf2read.c                      | 15 ++++++++++++++-
 gdb/testsuite/ChangeLog               |  4 ++++
 gdb/testsuite/gdb.ada/var_rec_arr.exp |  6 ++++++
 4 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 605eb39..437dbc2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-23  Joel Brobecker  <brobecker@adacore.com>
+
+	* dwarf2read.c (read_structure_type): Set the type's length
+	to zero if it has a DW_AT_byte_size attribute which is not
+	a constant.
+
 2015-11-23  Tristan Gingold  <gingold@adacore.com>
 
 	* darwin-nat.c (darwin_ptrace): Avoid a cast.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 48921e7..298757c 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13218,7 +13218,20 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
-      TYPE_LENGTH (type) = DW_UNSND (attr);
+      if (attr_form_is_constant (attr))
+        TYPE_LENGTH (type) = DW_UNSND (attr);
+      else
+	{
+	  /* For the moment, dynamic type sizes are not supported
+	     by GDB's struct type.  The actual size is determined
+	     on-demand when resolving the type of a given object,
+	     so set the type's length to zero for now.  Otherwise,
+	     we record an expression as the length, and that expression
+	     could lead to a very large value, which could eventually
+	     lead to us trying to allocate that much memory when creating
+	     a value of that type.  */
+          TYPE_LENGTH (type) = 0;
+	}
     }
   else
     {
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 68ede89..ee01eb6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-23  Joel Brobecker  <brobecker@adacore.com>
+
+	* testsuite/gdb.ada/var_rec_arr.exp: Add "ptype a1(1)" test.
+
 2015-11-20  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
         * gdb.base/callfuncs.exp (fetch_all_registers): Filter out the
diff --git a/gdb/testsuite/gdb.ada/var_rec_arr.exp b/gdb/testsuite/gdb.ada/var_rec_arr.exp
index 82ca857..66525e7 100644
--- a/gdb/testsuite/gdb.ada/var_rec_arr.exp
+++ b/gdb/testsuite/gdb.ada/var_rec_arr.exp
@@ -49,3 +49,9 @@ gdb_test "print a2(2)" \
 
 gdb_test "print a2(3)" \
          " = \\(i => 0, s => \"\"\\)"
+
+gdb_test "ptype a1(1)" \
+         [multi_line "type = record" \
+                     "    i: pck\\.small_type;" \
+                     "    s: access array \\((<>|1 \\.\\. i)\\) of character;" \
+                     "end record"]


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