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

Tom de Vries tdevries@suse.de
Wed Jun 23 12:04:54 GMT 2021


On 6/22/21 11:52 PM, Andrew Burgess wrote:
> * 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'm curious, could you elaborate on this?  In what situations did you
see a different order?

[ Not that I much mind not matching in order, it doesn't look terribly
important to me. ]

Anyway, I have a minor concern about this patch: that it is a local,
specific solution.  Ideally we specify some matching data that is
specific to the test-case, and pass it to a lib/gdb.exp proc, which is
generic enough to handle similar cases.

I tested the patch with check-read1, and no issues found.

Thanks,
- Tom

> 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