Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch] [VLA 2/2] Interpret FIELD_LOC_KIND_DWARF_BLOCK fields
@ 2009-01-13  1:42 Jan Kratochvil
  2009-01-19 15:22 ` Ulrich Weigand
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Kratochvil @ 2009-01-13  1:42 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joel Brobecker, Ulrich Weigand, Jim Blandy, Tobias Burnus

Hi,

this patch provides the interpreter for simple C variable length arrays (VLA).

check_typedef() will contain a memory leak with this patch.  This has been
fixed by Tom Tromey's + mine <type> garbage collector to be posted later from:
http://sourceware.org/gdb/wiki/ArcherBranchManagement
archer-jankratochvil-type-refcount

No regressions for both patches on x86_64-unknown-linux-gnu, Fedora gcc-4.3.2-7.


Thanks,
Jan


gdb/
2009-01-13  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Interpret FIELD_LOC_KIND_DWARF_BLOCK fields.
	* c-typeprint.c (c_type_print_varspec_suffix): Display a marker for the
	variable length arrays.
	* dwarf2loc.c (dwarf2_evaluate_loc_desc): Wrap the function body by
	a cleanup block.  Move the BATON variable with the DATA and SIZE
	evaluation to ...
	(dwarf_expr_prep_ctx): ... a new function here.
	(dwarf_locexpr_baton_eval): New function.
	* dwarf2loc.h (dwarf_locexpr_baton_eval): New declaration.
	* dwarf2read.c (read_subrange_type <dwarf2_attr_block>): Set
	TYPE_DYNAMIC for RANGE_TYPE.
	* gdbtypes.c: New include dwarf2loc.h.
	(create_array_type): Do not call get_discrete_bounds for TYPE_DYNAMIC
	types.  Fix/remove TYPE_TARGET_STUB which was set for static zero length
	arrays.  Call complaint for negative length static arrays.  Set
	TYPE_DYNAMIC appropriately for new RESULT_TYPE.
	(check_typedef): Make TYPE_DYNAMIC types parameters static.
	(create_copied_types_hash): Permit NULL OBJFILE.  Move the comment.
	(copy_type_recursive <FIELD_LOC_KIND_DWARF_BLOCK>): New.
	(copy_type_recursive): Clear TYPE_DYNAMIC for NEW_TYPE.
	* gdbtypes.h (TYPE_DYNAMIC): New define.
	(struct main_type): New field flag_dynamic.
	(TYPE_LENGTH): Update the comment for array types.

gdb/testsuite/
2009-01-13  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/vla.c, gdb.base/vla.exp: New.

--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/c-typeprint.c	2009-01-11 17:09:13.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/c-typeprint.c	2009-01-12 14:26:54.000000000 +0100
@@ -559,8 +559,13 @@ c_type_print_varspec_suffix (struct type
 	fprintf_filtered (stream, ")");
 
       fprintf_filtered (stream, "[");
-      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
-	&& !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
+      if (TYPE_DYNAMIC (TYPE_INDEX_TYPE (type)))
+	{
+	  /* Do not translate it as it is a part of the printed source.  */
+	  fprintf_filtered (stream, "variable");
+	}
+      else if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+	       && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
 	fprintf_filtered (stream, "%d",
 			  (TYPE_LENGTH (type)
 			   / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/dwarf2loc.c	2009-01-11 17:09:14.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/dwarf2loc.c	2009-01-12 22:43:25.000000000 +0100
@@ -191,6 +191,67 @@ dwarf_expr_tls_address (void *baton, COR
   return target_translate_tls_address (debaton->objfile, offset);
 }
 
+/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable
+   by dwarf_expr_fetch (RETVAL, 0).  FRAME parameter can be left NULL to call
+   get_selected_frame to get its value.  Freeing of returned dwarf_expr_context
+   is remembered on the current cleanup chain.  */
+
+static struct dwarf_expr_context *
+dwarf_expr_prep_ctx (struct frame_info *frame, gdb_byte *data,
+		     unsigned short size, struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+
+  if (!frame)
+    frame = get_selected_frame (NULL);
+
+  baton.frame = frame;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
+
+  ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_objfile_arch (baton.objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
+  ctx->baton = &baton;
+  ctx->read_reg = dwarf_expr_read_reg;
+  ctx->read_mem = dwarf_expr_read_mem;
+  ctx->get_frame_base = dwarf_expr_frame_base;
+  ctx->get_tls_address = dwarf_expr_tls_address;
+
+  make_cleanup ((make_cleanup_ftype *) free_dwarf_expr_context, ctx);
+
+  dwarf_expr_eval (ctx, data, size);
+
+  /* The field has been used only above during dwarf_expr_eval.  */
+  ctx->baton = NULL;
+
+  return ctx;
+}
+
+/* Evaluate DWARF expression at DLBATON expecting it produces exactly one
+   CORE_ADDR result on the DWARF stack stack.  */
+
+CORE_ADDR
+dwarf_locexpr_baton_eval (struct dwarf2_locexpr_baton *dlbaton)
+{
+  struct dwarf_expr_context *ctx;
+  CORE_ADDR retval;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+
+  ctx = dwarf_expr_prep_ctx (NULL, dlbaton->data, dlbaton->size,
+			     dlbaton->per_cu);
+  if (ctx->num_pieces > 0)
+    error (_("DW_OP_*piece is unsupported for DW_FORM_block"));
+  else if (ctx->in_reg)
+    error (_("Register result is unsupported for DW_FORM_block"));
+
+  retval = dwarf_expr_fetch (ctx, 0);
+
+  do_cleanups (back_to);
+
+  return retval;
+}
+
 /* Evaluate a location description, starting at DATA and with length
    SIZE, to find the current location of variable VAR in the context
    of FRAME.  */
@@ -201,8 +262,8 @@ dwarf2_evaluate_loc_desc (struct symbol 
 {
   struct gdbarch *arch = get_frame_arch (frame);
   struct value *retval;
-  struct dwarf_expr_baton baton;
   struct dwarf_expr_context *ctx;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
   if (size == 0)
     {
@@ -212,19 +273,8 @@ dwarf2_evaluate_loc_desc (struct symbol 
       return retval;
     }
 
-  baton.frame = frame;
-  baton.objfile = dwarf2_per_cu_objfile (per_cu);
-
-  ctx = new_dwarf_expr_context ();
-  ctx->gdbarch = get_objfile_arch (baton.objfile);
-  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
-  ctx->baton = &baton;
-  ctx->read_reg = dwarf_expr_read_reg;
-  ctx->read_mem = dwarf_expr_read_mem;
-  ctx->get_frame_base = dwarf_expr_frame_base;
-  ctx->get_tls_address = dwarf_expr_tls_address;
+  ctx = dwarf_expr_prep_ctx (frame, data, size, per_cu);
 
-  dwarf_expr_eval (ctx, data, size);
   if (ctx->num_pieces > 0)
     {
       int i;
@@ -270,7 +320,7 @@ dwarf2_evaluate_loc_desc (struct symbol 
 
   set_value_initialized (retval, ctx->initialized);
 
-  free_dwarf_expr_context (ctx);
+  do_cleanups (back_to);
 
   return retval;
 }
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/dwarf2loc.h	2009-01-11 17:09:14.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/dwarf2loc.h	2009-01-12 10:37:22.000000000 +0100
@@ -72,4 +72,7 @@ struct dwarf2_loclist_baton
 extern const struct symbol_ops dwarf2_locexpr_funcs;
 extern const struct symbol_ops dwarf2_loclist_funcs;
 
+extern CORE_ADDR dwarf_locexpr_baton_eval
+  (struct dwarf2_locexpr_baton *dlbaton);
+
 #endif /* dwarf2loc.h */
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/dwarf2read.c	2009-01-12 22:57:30.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/dwarf2read.c	2009-01-12 22:57:29.000000000 +0100
@@ -5171,6 +5171,7 @@ read_subrange_type (struct die_info *die
       SET_FIELD_DWARF_BLOCK (TYPE_FIELD (range_type, 0),
 			     dwarf_block_to_locexpr_baton (DW_BLOCK (attr),
 							   cu));
+      TYPE_DYNAMIC (range_type) = 1;
       break;
     }
 
@@ -5188,6 +5189,7 @@ read_subrange_type (struct die_info *die
       SET_FIELD_DWARF_BLOCK (TYPE_FIELD (range_type, 1),
 			     dwarf_block_to_locexpr_baton (DW_BLOCK (attr),
 							   cu));
+      TYPE_DYNAMIC (range_type) = 1;
       break;
     }
 
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/gdbtypes.c	2009-01-11 17:09:15.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/gdbtypes.c	2009-01-13 00:54:24.000000000 +0100
@@ -38,6 +38,7 @@
 #include "cp-abi.h"
 #include "gdb_assert.h"
 #include "hashtab.h"
+#include "dwarf2loc.h"
 
 /* These variables point to the objects
    representing the predefined C data types.  */
@@ -822,17 +823,6 @@ create_array_type (struct type *result_t
     }
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
-    low_bound = high_bound = 0;
-  CHECK_TYPEDEF (element_type);
-  /* Be careful when setting the array length.  Ada arrays can be
-     empty arrays with the high_bound being smaller than the low_bound.
-     In such cases, the array length should be zero.  */
-  if (high_bound < low_bound)
-    TYPE_LENGTH (result_type) = 0;
-  else
-    TYPE_LENGTH (result_type) =
-      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
   TYPE_NFIELDS (result_type) = 1;
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ALLOC (result_type, sizeof (struct field));
@@ -840,11 +830,44 @@ create_array_type (struct type *result_t
   TYPE_INDEX_TYPE (result_type) = range_type;
   TYPE_VPTR_FIELDNO (result_type) = -1;
 
-  /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
-  if (TYPE_LENGTH (result_type) == 0)
-    TYPE_TARGET_STUB (result_type) = 1;
+  /* The resulting array type needs to have evaluated the original TYPE_DYNAMIC
+     RANGE_TYPE expressions on each check_typedef call.  Therefore we mark
+     RESULT_TYPE by TYPE_TARGET_STUB and TYPE_LENGTH can be left unset for the
+     later check_typedef call by the RESULT_TYPE consumer.
+     TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED or TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED
+     will result in a non-TYPE_TARGET_STUB array with TYPE_LENGTH set to 0.  */
+  if (TYPE_TARGET_STUB (element_type)
+      || TYPE_DYNAMIC (range_type)
+      || get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+    {
+      TYPE_TARGET_STUB (result_type) = 1;
+      TYPE_LENGTH (result_type) = 0;
+    }
+  else if (high_bound + 1 < low_bound)
+    {
+      complaint (&symfile_complaints, _("Range type %s is invalid"),
+		 TYPE_NAME (range_type) ? TYPE_NAME (range_type) : "<NULL>");
+      TYPE_LENGTH (result_type) = 0;
+    }
+  else
+    {
+      CHECK_TYPEDEF (element_type);
+      TYPE_LENGTH (result_type) = TYPE_LENGTH (element_type)
+				  * (high_bound - low_bound + 1);
+    }
 
-  return (result_type);
+  /* Propagate FIELD_LOC_KIND_DWARF_BLOCK bounds.  */
+  if (TYPE_DYNAMIC (range_type))
+    TYPE_DYNAMIC (result_type) = 1;
+
+  /* Multidimensional TYPE_DYNAMIC arrays need to have all the outer dimensions
+     also TYPE_DYNAMIC.  check_typedef will have to update the TYPE_TARGET_TYPE
+     pointer in the outer dimension with the new type (+main_type) copy
+     containing the constant evaluated parameters.  */
+  if (TYPE_DYNAMIC (element_type))
+    TYPE_DYNAMIC (result_type) = 1;
+
+  return result_type;
 }
 
 /* Create a string type using either a blank type supplied in
@@ -1512,6 +1535,21 @@ check_typedef (struct type *type)
         }
     }
 
+  /* copy_type_recursive automatically makes the resulting type containing only
+     constant values expected by the callers of this function.
+     
+     FIXME: New TYPE memory leaks here on each check_typedef call.  */
+  if (TYPE_DYNAMIC (type))
+    {
+      htab_t copied_types;
+
+      copied_types = create_copied_types_hash (NULL);
+      type = copy_type_recursive (TYPE_OBJFILE (type), type, copied_types);
+      htab_delete (copied_types);
+
+      gdb_assert (TYPE_DYNAMIC (type) == 0);
+    }
+
   if (TYPE_TARGET_STUB (type))
     {
       struct type *range_type;
@@ -2915,16 +2953,21 @@ type_pair_eq (const void *item_lhs, cons
 }
 
 /* Allocate the hash table used by copy_type_recursive to walk
-   types without duplicates.  We use OBJFILE's obstack, because
-   OBJFILE is about to be deleted.  */
+   types without duplicates.   */
 
 htab_t
 create_copied_types_hash (struct objfile *objfile)
 {
-  return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
-			       NULL, &objfile->objfile_obstack,
-			       hashtab_obstack_allocate,
-			       dummy_obstack_deallocate);
+  if (objfile == NULL)
+    return htab_create (1, type_pair_hash, type_pair_eq, NULL);
+  else
+    {
+      /* Use OBJFILE's obstack, because OBJFILE is about to be deleted.  */
+      return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
+				   NULL, &objfile->objfile_obstack,
+				   hashtab_obstack_allocate,
+				   dummy_obstack_deallocate);
+    }
 }
 
 /* Recursively copy (deep copy) TYPE, if it is associated with
@@ -3010,6 +3053,12 @@ copy_type_recursive (struct objfile *obj
 				  xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type,
 								       i)));
 	      break;
+	    case FIELD_LOC_KIND_DWARF_BLOCK:
+	      /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
+		 it is expected to be made constant by check_typedef.  */
+	      SET_FIELD_BITPOS (TYPE_FIELD (new_type, i),
+		 dwarf_locexpr_baton_eval (TYPE_FIELD_DWARF_BLOCK (type, i)));
+	      break;
 	    default:
 	      internal_error (__FILE__, __LINE__,
 			      _("Unexpected type field location kind: %d"),
@@ -3018,6 +3067,9 @@ copy_type_recursive (struct objfile *obj
 	}
     }
 
+  /* FIELD_LOC_KIND_DWARF_BLOCK fields have been possibly converted.  */
+  TYPE_DYNAMIC (new_type) = 0;
+
   /* Copy pointers to other types.  */
   if (TYPE_TARGET_TYPE (type))
     TYPE_TARGET_TYPE (new_type) = 
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/gdbtypes.h	2009-01-11 19:37:36.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/gdbtypes.h	2009-01-13 00:25:22.000000000 +0100
@@ -209,6 +209,14 @@ enum type_instance_flag_value
 
 #define TYPE_TARGET_STUB(t)	(TYPE_MAIN_TYPE (t)->flag_target_stub)
 
+/* Type needs to be made static by check_typedef creating a new copy no longer
+   being TYPE_DYNAMIC.  Difference to TYPE_STUB or TYPE_TARGET_STUB is that the
+   original type must be preserved intact.  Check_typedef must return its copy
+   (of main_type, not just type).  For example FIELD_LOC_KIND_DWARF_BLOCK
+   fields will get resolved to the static form FIELD_LOC_KIND_BITPOS.  */
+
+#define TYPE_DYNAMIC(t)		(TYPE_MAIN_TYPE (t)->flag_dynamic)
+
 /* Static type.  If this is set, the corresponding type had 
  * a static modifier.
  * Note: This may be unnecessary, since static data members
@@ -352,6 +360,7 @@ struct main_type
   unsigned int flag_stub_supported : 1;
   unsigned int flag_nottext : 1;
   unsigned int flag_fixed_instance : 1;
+  unsigned int flag_dynamic : 1;
 
   /* Number of fields described for this type.  This field appears at
      this location because it packs nicely here.  */
@@ -795,9 +804,9 @@ extern void allocate_cplus_struct_type (
 #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
 #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
 #define TYPE_CHAIN(thistype) (thistype)->chain
-/* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
-   But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
-   so you only have to call check_typedef once.  Since allocate_value
+/* Note that if thistype is a TYPEDEF or ARRAY type, you have to call
+   check_typedef.  But check_typedef does set the TYPE_LENGTH of the TYPEDEF
+   type, so you only have to call check_typedef once.  Since allocate_value
    calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe.  */
 #define TYPE_LENGTH(thistype) (thistype)->length
 #define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/testsuite/gdb.base/vla.c	1970-01-01 01:00:00.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/testsuite/gdb.base/vla.c	2009-01-13 00:14:34.000000000 +0100
@@ -0,0 +1,55 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2009 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+void
+marker (void)
+{
+}
+
+void
+bar (char *a, char *b, char *c, int size)
+{
+  memset (a, '1', size);
+  memset (b, '2', size);
+  memset (c, '3', 48);
+}
+
+void
+foo (int size)
+{
+  char temp1[size];
+  char temp3[48];
+
+  temp1[size - 1] = '\0';
+  {
+    char temp2[size];
+
+    bar (temp1, temp2, temp3, size);
+
+    marker ();	/* break-here */
+  }
+}
+
+int
+main (void)
+{
+  foo (26);
+  foo (78);
+  return 0;
+}
--- gdb-cvs-dwarf2_get_attr_constant_value/gdb/testsuite/gdb.base/vla.exp	1970-01-01 01:00:00.000000000 +0100
+++ gdb-cvs-dwarf_block-eval/gdb/testsuite/gdb.base/vla.exp	2009-01-13 01:29:08.000000000 +0100
@@ -0,0 +1,81 @@
+# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test C variable length arrays.
+
+set srcfile vla.c
+
+if [prepare_for_testing vla.exp "vla"] {
+    return -1
+}
+if ![runto_main] {
+    untested vla.exp
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "break-here"
+
+# Set if the compiler has produced no DW_FORM_block*.
+set xfail 0
+
+set test "first: whatis temp1"
+gdb_test_multiple "whatis temp1" $test {
+    -re "type = char \\\[\\\]\r\n$gdb_prompt $" {
+	# Compiler has produced no DW_FORM_block*?
+	setup_xfail "*-*-*"
+	fail $test
+
+	set xfail 1
+    }
+    -re "type = char \\\[variable\\\]\r\n$gdb_prompt $" {
+	pass $test
+    }
+}
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2"
+gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3"
+
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1"
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2"
+gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3"
+
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "p temp1" "\\$\[0-9\]+ = '1' <repeats 26 times>" "first: print temp1"
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "p temp2" "\\$\[0-9\]+ = '2' <repeats 26 times>" "first: print temp2"
+gdb_test "p temp3" "\\$\[0-9\]+ = '3' <repeats 48 times>" "first: print temp3"
+
+gdb_continue_to_breakpoint "break-here"
+
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1"
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2"
+gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3"
+
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1"
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2"
+gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3"
+
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "p temp1" "\\$\[0-9\]+ = '1' <repeats 78 times>" "second: print temp1"
+if $xfail { setup_xfail "*-*-*" }
+gdb_test "p temp2" "\\$\[0-9\]+ = '2' <repeats 78 times>" "second: print temp2"
+gdb_test "p temp3" "\\$\[0-9\]+ = '3' <repeats 48 times>" "second: print temp3"


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

* Re: [patch] [VLA 2/2] Interpret FIELD_LOC_KIND_DWARF_BLOCK fields
  2009-01-13  1:42 [patch] [VLA 2/2] Interpret FIELD_LOC_KIND_DWARF_BLOCK fields Jan Kratochvil
@ 2009-01-19 15:22 ` Ulrich Weigand
  2009-01-20  3:57   ` Daniel Jacobowitz
  0 siblings, 1 reply; 3+ messages in thread
From: Ulrich Weigand @ 2009-01-19 15:22 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, Joel Brobecker, Jim Blandy, Tobias Burnus

Jan Kratochvil wrote:

> check_typedef() will contain a memory leak with this patch.  This has been
> fixed by Tom Tromey's + mine <type> garbage collector to be posted later from:
> http://sourceware.org/gdb/wiki/ArcherBranchManagement
> archer-jankratochvil-type-refcount

If this is a pre-req, I think we should get that in the tree first ...

> +/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable
> +   by dwarf_expr_fetch (RETVAL, 0).  FRAME parameter can be left NULL to call
> +   get_selected_frame to get its value.  Freeing of returned dwarf_expr_context
> +   is remembered on the current cleanup chain.  */
> +
> +static struct dwarf_expr_context *
> +dwarf_expr_prep_ctx (struct frame_info *frame, gdb_byte *data,
> +		     unsigned short size, struct dwarf2_per_cu_data *per_cu)
> +{
> +  struct dwarf_expr_context *ctx;
> +  struct dwarf_expr_baton baton;
> +
> +  if (!frame)
> +    frame = get_selected_frame (NULL);

I don't particularly like this.  We've been trying to get away from
having low-level routines depend on "global" setting like the currently
selected frame ...

Why is it correct to always evaluate VLA sizes relative to the currently
selected frame?  We might need to use some other frame, e.g. when re-
evaluating watchpoint expressions due to a shared-library event ...

It appears the need for using global data stems from the design decision
to have VLA sizes implicitly evaluated during the check_typedef call.
I'm wondering whether it wouldn't be better to use some other interface
to get at the current length of a VLA type, explicitly relative to a
specified frame (and possibly a specified data object).

B.t.w. this might also address the memory-management problem by not
having to allocate new types in the first place.

> --- gdb-cvs-dwarf2_get_attr_constant_value/gdb/dwarf2loc.h	2009-01-11 17:09:14.000000000 +0100
> +++ gdb-cvs-dwarf_block-eval/gdb/dwarf2loc.h	2009-01-12 10:37:22.000000000 +0100
> @@ -72,4 +72,7 @@ struct dwarf2_loclist_baton
>  extern const struct symbol_ops dwarf2_locexpr_funcs;
>  extern const struct symbol_ops dwarf2_loclist_funcs;
>  
> +extern CORE_ADDR dwarf_locexpr_baton_eval
> +  (struct dwarf2_locexpr_baton *dlbaton);

Making this dwarf2-specific function directly callable seems to break
the abstraction layer that "hides" specific details of any particular
debug info formati from common code.

However, I'm not sure I see a clean solution for this.  Ideally, we'd
have something like a LOC_COMPUTED with callback functions, to handle
format-specific field_loc_kind values.  But that would require adding
a new pointer to "struct field", which I don't really like either as
this is a quite space-critical data structure ...

I guess we can live for now with the broken abstraction, unless someone
has some better idea.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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

* Re: [patch] [VLA 2/2] Interpret FIELD_LOC_KIND_DWARF_BLOCK fields
  2009-01-19 15:22 ` Ulrich Weigand
@ 2009-01-20  3:57   ` Daniel Jacobowitz
  0 siblings, 0 replies; 3+ messages in thread
From: Daniel Jacobowitz @ 2009-01-20  3:57 UTC (permalink / raw)
  To: Ulrich Weigand
  Cc: Jan Kratochvil, gdb-patches, Joel Brobecker, Jim Blandy, Tobias Burnus

On Mon, Jan 19, 2009 at 04:21:10PM +0100, Ulrich Weigand wrote:
> Making this dwarf2-specific function directly callable seems to break
> the abstraction layer that "hides" specific details of any particular
> debug info formati from common code.
> 
> However, I'm not sure I see a clean solution for this.  Ideally, we'd
> have something like a LOC_COMPUTED with callback functions, to handle
> format-specific field_loc_kind values.  But that would require adding
> a new pointer to "struct field", which I don't really like either as
> this is a quite space-critical data structure ...

What fields use this - is it specific to array bounds?  If so can we
move it to a new array-specific extension to struct type?

-- 
Daniel Jacobowitz
CodeSourcery


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

end of thread, other threads:[~2009-01-20  3:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-13  1:42 [patch] [VLA 2/2] Interpret FIELD_LOC_KIND_DWARF_BLOCK fields Jan Kratochvil
2009-01-19 15:22 ` Ulrich Weigand
2009-01-20  3:57   ` Daniel Jacobowitz

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