[RFC PATCH] gdb/testsuite: fix gdb.base/info-types*.exp when no libc debug info

Andrew Burgess andrew.burgess@embecosm.com
Tue Jun 22 21:52:53 GMT 2021


* Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> [2021-06-22 13:24:47 -0400]:

> On Ubuntu 20.04, when the debug info package for libc is not installed,
> I get:
> 
>     FAIL: gdb.base/info-types-c++.exp: info types
>     FAIL: gdb.base/info-types-c.exp: info types
> 
> The reason is that the output of info types is exactly:
> 
>     (gdb) info types
>     All defined types:
> 
>     File /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/info-types.c:
>     52:     typedef enum {...} anon_enum_t;
>     45:     typedef struct {...} anon_struct_t;
>     68:     typedef union {...} anon_union_t;
>     28:     typedef struct baz_t baz;
>     31:     typedef struct baz_t * baz_ptr;
>     21:     struct baz_t;
>             double
>     33:     enum enum_t;
>             float
>             int
>     38:     typedef enum enum_t my_enum_t;
>     17:     typedef float my_float_t;
>     16:     typedef int my_int_t;
>     54:     typedef enum {...} nested_anon_enum_t;
>     47:     typedef struct {...} nested_anon_struct_t;
>     70:     typedef union {...} nested_anon_union_t;
>     30:     typedef struct baz_t nested_baz;
>     29:     typedef struct baz_t nested_baz_t;
>     39:     typedef enum enum_t nested_enum_t;
>     19:     typedef float nested_float_t;
>     18:     typedef int nested_int_t;
>     62:     typedef union union_t nested_union_t;
>     56:     union union_t;
>             unsigned int
>     (gdb)
> 
> The lines we expect in the test contain an empty line at the end:
> 
>     ...
>     "18:\[\t \]+typedef int nested_int_t;" \
>     "62:\[\t \]+typedef union_t nested_union_t;" \
>     "--optional" "\[\t \]+unsigned int" \
>     ""]
> 
> This is written with the supposition that other files will be listed, so
> an empty line will be included to separate the symbols from this file
> from the next one.  This empty line is not included when info-types.c is
> the only file listed.
> 
> This patch fixes the issue by not requiring an empty line.  I don't
> think it's a very good solution, however: the empty line ensures that
> there is no additional unexpected items after "unsigned int".
> 
> I don't think that making the empty line optional (with --optional)
> would achieve anything, since the lines would still match if there was
> some unexpected output.
> 
> So, I'll think about it a bit more, but any suggestions are appreciated.

What about the patch below?  Instead of using the builtin
gdb_test_lines, I grab the type lines (but just for $srcfile) using
gdb_test_multiple, then manually check for each type in turn.

We no longer care about the order of the types in the output, but I
think that is fine, the order was always pretty random anyway.

I don't have a ChangeLog or commit message for this, but feel free to
take this patch if you like the approach, or let me know and I can add
the missing bits.

Thanks,
Andrew

---

diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl
index c820adc4ac1..729ae23f367 100644
--- a/gdb/testsuite/gdb.base/info-types.exp.tcl
+++ b/gdb/testsuite/gdb.base/info-types.exp.tcl
@@ -39,13 +39,57 @@ proc run_test { lang } {
     }
 
     set file_re "File .*[string_to_regexp $srcfile]:"
+    set file_types {}
+    set collect_types False
+    set seen_header False
 
+    # Run 'info types' and collect all of the types associated with
+    # SRCFILE into the list FILE_TYPES.
+    gdb_test_multiple "info types" "" {
+	-re "^info types\r\n" {
+	    exp_continue
+	}
+	-re "^\r\n" {
+	    set collect_types False
+	    exp_continue
+	}
+	-re "^All defined types:\r\n" {
+	    set seen_header True
+	    exp_continue
+	}
+	-re "^(File \[^\r\n\]+:)\r\n" {
+	    set line $expect_out(1,string)
+	    if {[regexp ${file_re} ${line}]} {
+		set collect_types True
+	    } else {
+		set collect_types False
+	    }
+	    exp_continue
+	}
+	-re "^(\\d+:\\s+\[^\r\n\]+)\r\n" {
+	    if { $collect_types } {
+		lappend file_types $expect_out(1,string)
+	    }
+	    exp_continue
+	}
+	-re "^(\\s+\[^\r\n\]+)\r\n" {
+	    if { $collect_types } {
+		lappend file_types $expect_out(1,string)
+	    }
+	    exp_continue
+	}
+	-re "^$::gdb_prompt $" {
+	    gdb_assert { $seen_header }
+	}
+    }
+
+    # Get the list of all the types we expect to find in SRCFILE, as
+    # well as any optional types that might appear in SRCFILE.
+    # Optional types will depend on the compiler, these are just the
+    # ones we've seen so far.
     if { $lang == "c++" } {
-	set output_lines \
+	set required_types \
 	    [list \
-		 "All defined types:" \
-		 "--any" \
-		 $file_re \
 		 "98:\[\t \]+CL;" \
 		 "42:\[\t \]+anon_struct_t;" \
 		 "65:\[\t \]+anon_union_t;" \
@@ -74,15 +118,14 @@ proc run_test { lang } {
 		 "39:\[\t \]+typedef enum_t nested_enum_t;" \
 		 "19:\[\t \]+typedef float nested_float_t;" \
 		 "18:\[\t \]+typedef int nested_int_t;" \
-		 "62:\[\t \]+typedef union_t nested_union_t;" \
-		 "--optional" "\[\t \]+unsigned int" \
-		 ""]
+		 "62:\[\t \]+typedef union_t nested_union_t;"]
+
+	set optional_types \
+	    [list \
+		 "\[\t \]+unsigned int"]
     } else {
-	set output_lines \
+	set required_types \
 	    [list \
-		 "All defined types:" \
-		 "--any" \
-		 $file_re \
 		 "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \
 		 "45:\[\t \]+typedef struct {\\.\\.\\.} anon_struct_t;" \
 		 "68:\[\t \]+typedef union {\\.\\.\\.} anon_union_t;" \
@@ -105,12 +148,33 @@ proc run_test { lang } {
 		 "19:\[\t \]+typedef float nested_float_t;" \
 		 "18:\[\t \]+typedef int nested_int_t;" \
 		 "62:\[\t \]+typedef union union_t nested_union_t;" \
-		 "56:\[\t \]+union union_t;" \
-		 "--optional" "\[\t \]+unsigned int" \
-		 ""]
+		 "56:\[\t \]+union union_t;"]
+
+	set optional_types \
+	    [list \
+		 "\[\t \]+unsigned int"]
+    }
+
+    # Check that every required type was present.  As we find each
+    # type we remove it from FILE_TYPES.
+    foreach type_pattern $required_types {
+	set idx [lsearch -regexp $file_types ${type_pattern}]
+	gdb_assert { $idx != -1 } \
+	    "found type '${type_pattern}'"
+	set file_types [lreplace $file_types $idx $idx]
+    }
+
+    # Now remove each optional type.  Obviously we can't require that
+    # these be present (they're optional), but removing them now
+    # allows us to perform the next check (see below).
+    foreach type_pattern $optional_types {
+	set idx [lsearch -regexp $file_types ${type_pattern}]
+	set file_types [lreplace $file_types $idx $idx]
     }
 
-    gdb_test_lines "info types" "" $output_lines
+    # With all of the required and optional types removed from
+    # FILE_TYPES, the FILE_TYPES list should now be empty.
+    gdb_assert { [llength $file_types] == 0 }
 }
 
 run_test $lang


More information about the Gdb-patches mailing list