[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