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

RFC: DWARF reader -vs- unknown types


I plan to commit this, but as it touches on output formatting I figured
I would let people comment first.

Right now the DWARF reader simply throws an exception if it finds a type
it does not recognize.  This is not very friendly, because it results in
strange behavior from GDB.  In particular, it means that many commands
in GDB will simply print the same error message, as GDB tries over and
over to read the debuginfo.

You can easily reproduce this by using a very recent GCC to compile a
C++ program using rvalue references (-std=c++0x -gdwarf-4).  GDB does
not recognize DW_TAG_rvalue_reference_type, provoking the problem.  I
have also heard a report from someone who has their own compiler that
emits types in the vendor-defined tag range.

This patch changes the DWARF reader to create a new type using
TYPE_CODE_ERROR to represent the unrecognized type.  The type includes
enough information for the user to find the failing DIE.  (I think all
the DWARF error messages should include this information -- it makes
helping users much simpler.)

It also changes all the places in GDB that use TYPE_CODE_ERROR to print
the type's name rather than <unknown type>.

Here is what it looks like now when I try to print a variable of rvalue
reference type:

    (gdb) p r
    $1 = <unknown type in /tmp/q, CU 0x0, DIE 0x64>
    (gdb) ptype r
    type = <unknown type in /tmp/q, CU 0x0, DIE 0x64>

Built and regtested on x86-64 (compile farm).

Let me know what you think.  In the absence of comments I will commit it
before 7.2.

Tom

2010-06-17  Tom Tromey  <tromey@redhat.com>

	* p-valprint.c (pascal_val_print): Use TYPE_ERROR_NAME.
	* p-typeprint.c (pascal_type_print_base): Use TYPE_ERROR_NAME.
	* m2-valprint.c (m2_val_print): Use TYPE_ERROR_NAME.
	* gdbtypes.h (TYPE_ERROR_NAME): New macro.
	* f-valprint.c (f_val_print): Use TYPE_ERROR_NAME.
	* f-typeprint.c (f_type_print_base): Use TYPE_ERROR_NAME.
	* dwarf2read.c (tag_type_to_type): Create a new error type on
	failure.
	* c-valprint.c (c_val_print): Use TYPE_ERROR_NAME.
	* c-typeprint.c (c_type_print_base): Use TYPE_ERROR_NAME.

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 2697c3a..54be98f 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -1121,7 +1121,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, _("<unknown type>"));
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_RANGE:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 9d2da35..338faf5 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -552,7 +552,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, _("<error type>"));
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_UNDEF:
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6115939..b27db70 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -9151,9 +9151,18 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
   this_type = read_type_die (die, cu);
   if (!this_type)
     {
-      dump_die_for_error (die);
-      error (_("Dwarf Error: Cannot find type of die [in module %s]"), 
-	     cu->objfile->name);
+      char *message, *saved;
+
+      /* read_type_die already issued a complaint.  */
+      message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
+			    cu->objfile->name,
+			    cu->header.offset,
+			    die->offset);
+      saved = obstack_copy0 (&cu->objfile->objfile_obstack,
+			     message, strlen (message));
+      xfree (message);
+
+      this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, cu->objfile);
     }
   return this_type;
 }
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1343f68..9f8c45a 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -312,7 +312,7 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintfi_filtered (level, stream, "<unknown type>");
+      fprintfi_filtered (level, stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_RANGE:
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index acd6487..6259d87 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -394,7 +394,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, "<error type>");
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_RANGE:
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 32e5f04..ce79dc2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1054,6 +1054,11 @@ extern void allocate_gnat_aux_type (struct type *);
 				   || TYPE_NFN_FIELDS (thistype) == 0) &&		\
                                   (TYPE_STUB (thistype) || !TYPE_STUB_SUPPORTED (thistype)))
 
+/* A helper macro that returns the name of an error type.  If the type
+   has a name, it is used; otherwise, a default is used.  */
+#define TYPE_ERROR_NAME(type) \
+  (TYPE_NAME (type) ? TYPE_NAME (type) : _("<error type>"))
+
 struct builtin_type
 {
   /* Integral types.  */
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index edfd324..786cf20 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -646,7 +646,7 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, _("<error type>"));
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_UNDEF:
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index fc54e01..bf183f6 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -758,7 +758,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, "<unknown type>");
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
       /* this probably does not work for enums */
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index e58f9d2..5d06492 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -539,7 +539,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, "<error type>");
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
       break;
 
     case TYPE_CODE_UNDEF:


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