Make language setting tests more robust
Commit Message
This patch robustifies the setting of the language in gdb. Right now most of
the tests assume "set language" is a silent command and use gdb_test_no_output
for testing, but it may output a warning stating the language the user wants
to select does not match the frame's language. When this happens we have a
failure. This is also the case with "show language", where it outputs the
language currently-selected but may also output said warning.
One case of the warning being displayed happens when one has debug information
for glibc, which may cause GDB to identify the frame as having an "asm"
language. Therefore setting it to something else will get GDB's attention.
This patch addresses the problem by creating a function in lib/gdb.exp to
set the language. That function will also handle potential warnings and check
to make sure the language was properly selected.
Also, i noticed most of the languages have their own set_lang_<language> proc,
and they are all the same. Therefore i've removed those and switched to using
only the new set_language proc.
I tried to confirm why set_lang_<language> was replicated, but my conclusion
was that it was just the way the code worked and people just copy/pasted from
an existing language .exp file.
Overall i see no regressions with Ubuntu 16.04 x86-64, though the number of
tests changed slightly due to the way set_language works. No additional
failures nonetheless.
2017-02-01 Luis Machado <lgustavo@codesourcery.com>
* gdb.arch/i386-stap-eval-lang-ada.exp: Use new set_language proc.
* gdb.base/callfuncs.exp: Likewise.
* gdb.compile/compile-ifunc.exp: Likewise.
* gdb.cp/classes.exp: Likewise.
* gdb.cp/cmpd-minsyms.exp: Likewise.
* gdb.cp/cplusfuncs.exp: Likewise.
* gdb.cp/debug-expr.exp: Likewise.
* gdb.cp/demangle.exp: Likewise.
* gdb.cp/expand-psymtabs-cxx.exp: Likewise.
* gdb.cp/inherit.exp: Likewise.
* gdb.cp/overload-const.exp: Likewise.
* gdb.cp/psymtab-parameter.exp: Likewise.
* gdb.cp/ptype-flags.exp: Likewise.
* gdb.cp/typedef-operator.exp: Likewise.
* gdb.cp/var-tag.exp: Likewise.
* gdb.cp/virtfunc.exp: Likewise.
* gdb.dlang/circular.exp: Likewise.
* gdb.dlang/debug-expr.exp: Likewise.
* gdb.dlang/demangle.exp: Likewise.
* gdb.dlang/expression.exp: Likewise.
* gdb.dlang/primitive-types.exp: Likewise.
* gdb.dlang/properties.exp: Likewise.
* gdb.dwarf2/arr-stride.exp: Likewise.
* gdb.dwarf2/arr-subrange.exp: Likewise.
* gdb.dwarf2/data-loc.exp: Likewise.
* gdb.dwarf2/dw2-cp-infcall-ref-static.exp: Likewise.
* gdb.dwarf2/dw2-linkage-name-trust.exp: Likewise.
* gdb.dwarf2/dynarr-ptr.exp: Likewise.
* gdb.dwarf2/subrange.exp: Likewise.
* gdb.fortran/exprs.exp: Likewise.
* gdb.fortran/types.exp: Likewise.
* gdb.go/basic-types.exp: Likewise.
* gdb.go/print.exp: Likewise.
* gdb.objc/print.exp: Likewise.
* gdb.opencl/datatypes.exp: Likewise.
* gdb.pascal/print.exp: Likewise.
* gdb.pascal/types.exp: Likewise.
* gdb.python/py-lookup-type.exp: Likewise.
* gdb.rust/expr.exp: Likewise.
* lib/d-support.exp (set_lang_d): Remove.
* lib/fortran.exp (set_lang_fortran): Remove.
* lib/gdb.exp (set_language): New proc.
* lib/go.exp (set_lang_go): Remove.
* lib/objc.exp (set_lang_objc): Remove.
* lib/pascal.exp (set_lang_pascal): Remove.
* lib/rust-support.exp (set_lang_rust): Remove.
---
gdb/testsuite/gdb.arch/i386-stap-eval-lang-ada.exp | 2 +-
gdb/testsuite/gdb.base/callfuncs.exp | 2 +-
gdb/testsuite/gdb.compile/compile-ifunc.exp | 2 +-
gdb/testsuite/gdb.cp/classes.exp | 2 +-
gdb/testsuite/gdb.cp/cmpd-minsyms.exp | 2 +-
gdb/testsuite/gdb.cp/cplusfuncs.exp | 2 +-
gdb/testsuite/gdb.cp/debug-expr.exp | 2 +-
gdb/testsuite/gdb.cp/demangle.exp | 4 +--
gdb/testsuite/gdb.cp/expand-psymtabs-cxx.exp | 2 +-
gdb/testsuite/gdb.cp/inherit.exp | 2 +-
gdb/testsuite/gdb.cp/overload-const.exp | 2 +-
gdb/testsuite/gdb.cp/psymtab-parameter.exp | 2 +-
gdb/testsuite/gdb.cp/ptype-flags.exp | 2 +-
gdb/testsuite/gdb.cp/typedef-operator.exp | 2 +-
gdb/testsuite/gdb.cp/var-tag.exp | 4 +--
gdb/testsuite/gdb.cp/virtfunc.exp | 2 +-
gdb/testsuite/gdb.dlang/circular.exp | 2 +-
gdb/testsuite/gdb.dlang/debug-expr.exp | 2 +-
gdb/testsuite/gdb.dlang/demangle.exp | 2 +-
gdb/testsuite/gdb.dlang/expression.exp | 2 +-
gdb/testsuite/gdb.dlang/primitive-types.exp | 2 +-
gdb/testsuite/gdb.dlang/properties.exp | 2 +-
gdb/testsuite/gdb.dwarf2/arr-stride.exp | 2 +-
gdb/testsuite/gdb.dwarf2/arr-subrange.exp | 2 +-
gdb/testsuite/gdb.dwarf2/data-loc.exp | 2 +-
.../gdb.dwarf2/dw2-cp-infcall-ref-static.exp | 2 +-
.../gdb.dwarf2/dw2-linkage-name-trust.exp | 2 +-
gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 2 +-
gdb/testsuite/gdb.dwarf2/subrange.exp | 2 +-
gdb/testsuite/gdb.fortran/exprs.exp | 2 +-
gdb/testsuite/gdb.fortran/types.exp | 2 +-
gdb/testsuite/gdb.go/basic-types.exp | 2 +-
gdb/testsuite/gdb.go/print.exp | 2 +-
gdb/testsuite/gdb.objc/print.exp | 2 +-
gdb/testsuite/gdb.opencl/datatypes.exp | 6 ++--
gdb/testsuite/gdb.pascal/print.exp | 2 +-
gdb/testsuite/gdb.pascal/types.exp | 2 +-
gdb/testsuite/gdb.python/py-lookup-type.exp | 2 +-
gdb/testsuite/gdb.rust/expr.exp | 2 +-
gdb/testsuite/lib/d-support.exp | 11 ------
gdb/testsuite/lib/fortran.exp | 11 ------
gdb/testsuite/lib/gdb.exp | 41 ++++++++++++++++++++++
gdb/testsuite/lib/go.exp | 11 ------
gdb/testsuite/lib/objc.exp | 11 ------
gdb/testsuite/lib/pascal.exp | 14 --------
gdb/testsuite/lib/rust-support.exp | 10 ------
46 files changed, 84 insertions(+), 111 deletions(-)
Comments
On 2017-02-01 10:17, Luis Machado wrote:
> This patch robustifies the setting of the language in gdb. Right now
> most of
> the tests assume "set language" is a silent command and use
> gdb_test_no_output
> for testing, but it may output a warning stating the language the user
> wants
> to select does not match the frame's language. When this happens we
> have a
> failure. This is also the case with "show language", where it outputs
> the
> language currently-selected but may also output said warning.
>
> One case of the warning being displayed happens when one has debug
> information
> for glibc, which may cause GDB to identify the frame as having an "asm"
> language. Therefore setting it to something else will get GDB's
> attention.
>
> This patch addresses the problem by creating a function in lib/gdb.exp
> to
> set the language. That function will also handle potential warnings and
> check
> to make sure the language was properly selected.
>
> Also, i noticed most of the languages have their own
> set_lang_<language> proc,
> and they are all the same. Therefore i've removed those and switched
> to using
> only the new set_language proc.
>
> I tried to confirm why set_lang_<language> was replicated, but my
> conclusion
> was that it was just the way the code worked and people just
> copy/pasted from
> an existing language .exp file.
>
> Overall i see no regressions with Ubuntu 16.04 x86-64, though the
> number of
> tests changed slightly due to the way set_language works. No
> additional
> failures nonetheless.
I have just looked at the stuff in lib/, it looks good to me, that's a
nice cleanup. A few comments below.
> diff --git a/gdb/testsuite/lib/d-support.exp
> b/gdb/testsuite/lib/d-support.exp
> index ed568d3..100fb63 100644
> --- a/gdb/testsuite/lib/d-support.exp
> +++ b/gdb/testsuite/lib/d-support.exp
> @@ -16,17 +16,6 @@
> # Auxiliary function to set the language to D.
> # The result is 1 (true) for success, 0 (false) for failure.
Remove this comment.
> -proc set_lang_d {} {
> - if [gdb_test_no_output "set language d"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is \"d\"." \
> - "set language to \"d\""] {
> - return 0
> - }
> - return 1
> -}
> -
> # D version of runto_main.
>
> proc d_runto_main { } {
> diff --git a/gdb/testsuite/lib/fortran.exp
> b/gdb/testsuite/lib/fortran.exp
> index 867e4fc..2f4820b 100644
> --- a/gdb/testsuite/lib/fortran.exp
> +++ b/gdb/testsuite/lib/fortran.exp
> @@ -18,17 +18,6 @@
> # Auxiliary function to set the language to fortran.
> # The result is 1 (true) for success, 0 (false) for failure.
Comment.
> -proc set_lang_fortran {} {
> - if [gdb_test_no_output "set language fortran"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is \"fortran\"."
> \
> - "set language to \"fortran\""] {
> - return 0
> - }
> - return 1
> -}
> -
> proc fortran_int4 {} {
> if {[test_compiler_info {gcc-4-[012]-*}]} {
> return "int4"
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 48bd7ee..327bce8 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -6018,6 +6018,47 @@ proc multi_line_input { args } {
> return [join $args "\n"]
> }
>
> +# Set the language and handle possible warnings output by GDB if we
> select a
> +# language that differs from the current frame's language.
> +#
> +# The first argument is the language to set.
> +# The second argument is an optional message to be output by the test.
> +
> +proc set_language { args } {
Instead of "args", it might be clearer to use a default argument for the
second arg:
proc set_language { language { message "" } } {
And lower:
if { $message == "" } {
set message $command
}
Not sure about the exact TCL syntax, but I think you get the point :).
> + global gdb_prompt
> +
> + set language [lindex $args 0]
> + set command "set language $language"
> + set lang_pattern [string_to_regexp $language]
> +
> + # Do we have an optional user-provided test message?
> + if {[llength $args] > 1} {
> + set message [lindex $args 1]
> + } else {
> + set message $command
> + }
> +
> + # Switch to the user-selected language.
> + gdb_test_multiple $command $message {
> + -re "Undefined item: \"$lang_pattern\"\.\[\r\n\]+$gdb_prompt" {
> + fail $message
> + return 0
> + }
> + -re "Warning: the current language does not match this
> frame.\[\r\n\]+$gdb_prompt $" {
> + }
> + -re "$gdb_prompt $" {}
> + }
Do you want to add a "pass" in there somewhere, or we keep it silent if
it succeeds?
> +
> + # Verify the language has been set correctly. GDB may output a
> warning
> + # stating the user-provided language doesn't match the frame's
> language.
> + # We ignore that warning for testing purposes.
> + if {$language != "auto"} {
> + if [gdb_test "show language" ".* source language is
> \"$lang_pattern\".*" $message] {
> + return 0
> + }
> + }
In the else, you could verify that it matches 'The current source
language is "auto; currently .*"'.
> + return 1
> +}
>
> # Always load compatibility stuff.
> load_lib future.exp
> diff --git a/gdb/testsuite/lib/go.exp b/gdb/testsuite/lib/go.exp
> index c29b7c1..cb98bdc 100644
> --- a/gdb/testsuite/lib/go.exp
> +++ b/gdb/testsuite/lib/go.exp
> @@ -19,17 +19,6 @@
> # Auxiliary function to set the language to Go.
> # The result is 1 (true) for success, 0 (false) for failure.
Comment.
> -proc set_lang_go {} {
> - if [gdb_test_no_output "set language go"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is \"go\"." \
> - "set language to \"go\""] {
> - return 0
> - }
> - return 1
> -}
> -
> # Go version of runto_main.
>
> proc go_runto_main { } {
> diff --git a/gdb/testsuite/lib/objc.exp b/gdb/testsuite/lib/objc.exp
> index 7189f03..9891758 100644
> --- a/gdb/testsuite/lib/objc.exp
> +++ b/gdb/testsuite/lib/objc.exp
> @@ -17,14 +17,3 @@
>
> # Auxiliary function to set the language to fortran.
> # The result is 1 (true) for success, 0 (false) for failure.
Comment. Also, note that it mentions fortran :). Actually, you could
probably just delete that file.
> -
> -proc set_lang_objc {} {
> - if [gdb_test_no_output "set language objective-c"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is
> \"objective-c\"." \
> - "set language to \"objective-c\""] {
> - return 0
> - }
> - return 1
> -}
> diff --git a/gdb/testsuite/lib/pascal.exp
> b/gdb/testsuite/lib/pascal.exp
> index a0562c3..f0eb36b 100644
> --- a/gdb/testsuite/lib/pascal.exp
> +++ b/gdb/testsuite/lib/pascal.exp
> @@ -167,17 +167,3 @@ proc gdb_compile_pascal {source destfile type
> options} {
> return "Pascal compilation failed."
> }
> }
> -
> -# Auxiliary function to set the language to pascal.
> -# The result is 1 (true) for success, 0 (false) for failure.
> -
> -proc set_lang_pascal {} {
> - if [gdb_test_no_output "set language pascal"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is \"pascal\"." \
> - "set language to \"pascal\""] {
> - return 0
> - }
> - return 1
> -}
> diff --git a/gdb/testsuite/lib/rust-support.exp
> b/gdb/testsuite/lib/rust-support.exp
> index 2a12cca..a80d60b 100644
> --- a/gdb/testsuite/lib/rust-support.exp
> +++ b/gdb/testsuite/lib/rust-support.exp
> @@ -15,16 +15,6 @@
>
> # Auxiliary function to set the language to Rust.
> # The result is 1 (true) for success, 0 (false) for failure.
Comment.
> -proc set_lang_rust {} {
> - if [gdb_test_no_output "set language rust"] {
> - return 0
> - }
> - if [gdb_test "show language" ".* source language is \"rust\"." \
> - "set language to \"rust\""] {
> - return 0
> - }
> - return 1
> -}
>
> proc gdb_compile_rust {sources dest options} {
> if {[llength $sources] > 1} {
On 02/01/2017 12:38 PM, Simon Marchi wrote:
> On 2017-02-01 10:17, Luis Machado wrote:
>> This patch robustifies the setting of the language in gdb. Right now
>> most of
>> the tests assume "set language" is a silent command and use
>> gdb_test_no_output
>> for testing, but it may output a warning stating the language the user
>> wants
>> to select does not match the frame's language. When this happens we
>> have a
>> failure. This is also the case with "show language", where it outputs the
>> language currently-selected but may also output said warning.
>>
>> One case of the warning being displayed happens when one has debug
>> information
>> for glibc, which may cause GDB to identify the frame as having an "asm"
>> language. Therefore setting it to something else will get GDB's
>> attention.
>>
>> This patch addresses the problem by creating a function in lib/gdb.exp to
>> set the language. That function will also handle potential warnings
>> and check
>> to make sure the language was properly selected.
>>
>> Also, i noticed most of the languages have their own
>> set_lang_<language> proc,
>> and they are all the same. Therefore i've removed those and switched
>> to using
>> only the new set_language proc.
>>
>> I tried to confirm why set_lang_<language> was replicated, but my
>> conclusion
>> was that it was just the way the code worked and people just
>> copy/pasted from
>> an existing language .exp file.
>>
>> Overall i see no regressions with Ubuntu 16.04 x86-64, though the
>> number of
>> tests changed slightly due to the way set_language works. No additional
>> failures nonetheless.
>
> I have just looked at the stuff in lib/, it looks good to me, that's a
> nice cleanup. A few comments below.
>
>> diff --git a/gdb/testsuite/lib/d-support.exp
>> b/gdb/testsuite/lib/d-support.exp
>> index ed568d3..100fb63 100644
>> --- a/gdb/testsuite/lib/d-support.exp
>> +++ b/gdb/testsuite/lib/d-support.exp
>> @@ -16,17 +16,6 @@
>> # Auxiliary function to set the language to D.
>> # The result is 1 (true) for success, 0 (false) for failure.
>
> Remove this comment.
>
Oops. I was chasing some small issues with the set_language proc and
ended up forgetting the cleanup these files.
Thanks for catching that.
>> +# Set the language and handle possible warnings output by GDB if we
>> select a
>> +# language that differs from the current frame's language.
>> +#
>> +# The first argument is the language to set.
>> +# The second argument is an optional message to be output by the test.
>> +
>> +proc set_language { args } {
>
> Instead of "args", it might be clearer to use a default argument for the
> second arg:
>
> proc set_language { language { message "" } } {
>
> And lower:
>
> if { $message == "" } {
> set message $command
> }
>
> Not sure about the exact TCL syntax, but I think you get the point :).
>
I'm fine with that. I was mostly making it work like gdb_test_no_output.
I'll get this addressed in the next iteration.
>> + global gdb_prompt
>> +
>> + set language [lindex $args 0]
>> + set command "set language $language"
>> + set lang_pattern [string_to_regexp $language]
>> +
>> + # Do we have an optional user-provided test message?
>> + if {[llength $args] > 1} {
>> + set message [lindex $args 1]
>> + } else {
>> + set message $command
>> + }
>> +
>> + # Switch to the user-selected language.
>> + gdb_test_multiple $command $message {
>> + -re "Undefined item: \"$lang_pattern\"\.\[\r\n\]+$gdb_prompt" {
>> + fail $message
>> + return 0
>> + }
>> + -re "Warning: the current language does not match this
>> frame.\[\r\n\]+$gdb_prompt $" {
>> + }
>> + -re "$gdb_prompt $" {}
>> + }
>
> Do you want to add a "pass" in there somewhere, or we keep it silent if
> it succeeds?
>
The way the code works at the moment will give a PASS if we set the
language and then verify it has been set correctly. If it is not set
correctly, we get a FAIL.
>> +
>> + # Verify the language has been set correctly. GDB may output a
>> warning
>> + # stating the user-provided language doesn't match the frame's
>> language.
>> + # We ignore that warning for testing purposes.
>> + if {$language != "auto"} {
>> + if [gdb_test "show language" ".* source language is
>> \"$lang_pattern\".*" $message] {
>> + return 0
>> + }
>> + }
>
> In the else, you could verify that it matches 'The current source
> language is "auto; currently .*"'.
>
Yeah, that sounds reasonable. I'll address this.
>> + return 1
>> +}
>>
>> # Always load compatibility stuff.
>> load_lib future.exp
>> diff --git a/gdb/testsuite/lib/go.exp b/gdb/testsuite/lib/go.exp
>> index c29b7c1..cb98bdc 100644
>> --- a/gdb/testsuite/lib/go.exp
>> +++ b/gdb/testsuite/lib/go.exp
>> @@ -19,17 +19,6 @@
>> # Auxiliary function to set the language to Go.
>> # The result is 1 (true) for success, 0 (false) for failure.
>
> Comment.
>
>> -proc set_lang_go {} {
>> - if [gdb_test_no_output "set language go"] {
>> - return 0
>> - }
>> - if [gdb_test "show language" ".* source language is \"go\"." \
>> - "set language to \"go\""] {
>> - return 0
>> - }
>> - return 1
>> -}
>> -
>> # Go version of runto_main.
>>
>> proc go_runto_main { } {
>> diff --git a/gdb/testsuite/lib/objc.exp b/gdb/testsuite/lib/objc.exp
>> index 7189f03..9891758 100644
>> --- a/gdb/testsuite/lib/objc.exp
>> +++ b/gdb/testsuite/lib/objc.exp
>> @@ -17,14 +17,3 @@
>>
>> # Auxiliary function to set the language to fortran.
>> # The result is 1 (true) for success, 0 (false) for failure.
>
> Comment. Also, note that it mentions fortran :). Actually, you could
> probably just delete that file.
>
I considered just leaving it there, but with just the copyright.
Deleting may be cleaner though. What others think?
>> -
>> -proc set_lang_objc {} {
>> - if [gdb_test_no_output "set language objective-c"] {
>> - return 0
>> - }
>> - if [gdb_test "show language" ".* source language is
>> \"objective-c\"." \
>> - "set language to \"objective-c\""] {
>> - return 0
>> - }
>> - return 1
>> -}
>> diff --git a/gdb/testsuite/lib/pascal.exp b/gdb/testsuite/lib/pascal.exp
>> index a0562c3..f0eb36b 100644
>> --- a/gdb/testsuite/lib/pascal.exp
>> +++ b/gdb/testsuite/lib/pascal.exp
>> @@ -167,17 +167,3 @@ proc gdb_compile_pascal {source destfile type
>> options} {
>> return "Pascal compilation failed."
>> }
>> }
>> -
>> -# Auxiliary function to set the language to pascal.
>> -# The result is 1 (true) for success, 0 (false) for failure.
>> -
>> -proc set_lang_pascal {} {
>> - if [gdb_test_no_output "set language pascal"] {
>> - return 0
>> - }
>> - if [gdb_test "show language" ".* source language is \"pascal\"." \
>> - "set language to \"pascal\""] {
>> - return 0
>> - }
>> - return 1
>> -}
>> diff --git a/gdb/testsuite/lib/rust-support.exp
>> b/gdb/testsuite/lib/rust-support.exp
>> index 2a12cca..a80d60b 100644
>> --- a/gdb/testsuite/lib/rust-support.exp
>> +++ b/gdb/testsuite/lib/rust-support.exp
>> @@ -15,16 +15,6 @@
>>
>> # Auxiliary function to set the language to Rust.
>> # The result is 1 (true) for success, 0 (false) for failure.
>
> Comment.
>
>> -proc set_lang_rust {} {
>> - if [gdb_test_no_output "set language rust"] {
>> - return 0
>> - }
>> - if [gdb_test "show language" ".* source language is \"rust\"." \
>> - "set language to \"rust\""] {
>> - return 0
>> - }
>> - return 1
>> -}
>>
>> proc gdb_compile_rust {sources dest options} {
>> if {[llength $sources] > 1} {
>
>
Thanks for the review.
On 2017-02-01 14:22, Luis Machado wrote:
> The way the code works at the moment will give a PASS if we set the
> language and then verify it has been set correctly. If it is not set
> correctly, we get a FAIL.
Oh ok it makes sense.
Not to belabor the point, but...
On 02/01/2017 10:38 AM, Simon Marchi wrote:
>>
>> +# Set the language and handle possible warnings output by GDB if we
>> select a
>> +# language that differs from the current frame's language.
>> +#
>> +# The first argument is the language to set.
>> +# The second argument is an optional message to be output by the test.
>> +
>> +proc set_language { args } {
>
> Instead of "args", it might be clearer to use a default argument for the
> second arg:
>
> proc set_language { language { message "" } } {
>
> And lower:
>
> if { $message == "" } {
> set message $command
> }
>
> Not sure about the exact TCL syntax, but I think you get the point :).
>
Yes, your syntax looks correct to me. [I was in the process of writing
exactly the same thing.]
Regarding gdb_test_no_output et al, this grokking of args needs to be
banished from the test suite. It adds unnecessary complexity. I would
encourage maintainers to request revision when such a thing is proposed
for the test suite.
As a heads up/reminder, we also have parse_args, which is suitable for
more advanced use cases, involving multiple optional arguments and
flags. mi_make_breakpoint is one such place that demonstrates the use of
this facility.
Keith
On 02/01/2017 03:50 PM, Keith Seitz wrote:
> Not to belabor the point, but...
>
> On 02/01/2017 10:38 AM, Simon Marchi wrote:
>>>
>>> +# Set the language and handle possible warnings output by GDB if we
>>> select a
>>> +# language that differs from the current frame's language.
>>> +#
>>> +# The first argument is the language to set.
>>> +# The second argument is an optional message to be output by the test.
>>> +
>>> +proc set_language { args } {
>>
>> Instead of "args", it might be clearer to use a default argument for the
>> second arg:
>>
>> proc set_language { language { message "" } } {
>>
>> And lower:
>>
>> if { $message == "" } {
>> set message $command
>> }
>>
>> Not sure about the exact TCL syntax, but I think you get the point :).
>>
>
> Yes, your syntax looks correct to me. [I was in the process of writing
> exactly the same thing.]
>
> Regarding gdb_test_no_output et al, this grokking of args needs to be
> banished from the test suite. It adds unnecessary complexity. I would
> encourage maintainers to request revision when such a thing is proposed
> for the test suite.
Thanks for the input. Nice to have that in mind for the future. It does
look slightly convoluted.
>
> As a heads up/reminder, we also have parse_args, which is suitable for
> more advanced use cases, involving multiple optional arguments and
> flags. mi_make_breakpoint is one such place that demonstrates the use of
> this facility.
I'll check it out.
On 2017-02-01 16:50, Keith Seitz wrote:
> Regarding gdb_test_no_output et al, this grokking of args needs to be
> banished from the test suite. It adds unnecessary complexity. I would
> encourage maintainers to request revision when such a thing is proposed
> for the test suite.
Ok, good to know I'm not the only one :). When I encounter procs that
use this pattern, I have to either:
A. Pray that the documentation is still up to date
B. Read the code to decode what's being used where
Both are not very fun.
@@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
return -1
}
-gdb_test_no_output "set language ada"
+set_language "ada"
if { ![runto "-pstap bar"] } {
return -1
@@ -303,7 +303,7 @@ proc rerun_and_prepare {} {
gdb_suppress_tests
}
- gdb_test_no_output "set language c"
+ set_language "c"
get_debug_format
@@ -29,7 +29,7 @@ with_test_prefix "nodebug" {
# GDB happened to see real asm code when it stopped at the entry point
# when talking to a remote target, like gdbserver. This guarantees the
# feature check below will work.
- gdb_test_no_output "set language c" ""
+ set_language "c"
if {[skip_compile_feature_tests]} {
untested "compile command not supported (could not find libcc1 shared library?)"
@@ -551,7 +551,7 @@ proc do_tests {} {
global nl
- gdb_test_no_output "set language c++" ""
+ set_language "c++"
gdb_test_no_output "set width 0" ""
if ![runto_main ] then {
@@ -40,7 +40,7 @@ foreach sym $min_syms {
}
-gdb_test_no_output "set language c++"
+set_language "c++"
# A list of minimal symbol names to check.
# Note that GDB<char>::even_harder<int>(char) is quoted and includes
@@ -584,7 +584,7 @@ proc do_tests {} {
runto_main
- gdb_test_no_output "set language c++"
+ set_language "c++"
probe_demangler
test_paddr_overloaded_functions
test_paddr_operator_functions
@@ -18,7 +18,7 @@
if { [skip_cplus_tests] } { continue }
gdb_start
-gdb_test_no_output "set language c++"
+set_language "c++"
gdb_test_no_output "set debug expression 1"
# Test whether the expression debug machinery accepts the expression.
@@ -1547,7 +1547,7 @@ proc do_tests {} {
gdb_exit
gdb_start
- gdb_test_no_output "set language c++"
+ set_language "c++"
gdb_test_no_output "set width 0"
# Using catch_demangling_errors this way ensures that, if one of
@@ -1559,7 +1559,7 @@ proc do_tests {} {
catch_demangling_errors test_hp_style_demangling
# Verify specifying demangle language.
- gdb_test_no_output "set language unknown"
+ set_language "unknown"
set_demangling_style "auto"
gdb_test_exact "demangle -l c++ -- _ZSt4cout" "std::cout"
gdb_test_exact "demangle -l c++ _ZSt4cout" "std::cout"
@@ -26,7 +26,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {debug c
clean_restart ${executable}
-gdb_test_no_output "set language c++"
+set_language "c++"
# FAIL was:
# $1 = {<text variable, no debug info>} 0
@@ -682,7 +682,7 @@ proc do_tests { } {
return
}
- gdb_test_no_output "set language c++"
+ set_language "c++"
test_ptype_si
test_ptype_mi
test_ptype_vi
@@ -23,7 +23,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $testfile.cc {c++ debug}]
return -1
}
-gdb_test_no_output "set language c++"
+set_language "c++"
if [gdb_breakpoint "myclass::func"] {
pass "setting breakpoint at myclass::func"
@@ -25,7 +25,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}.x" object {debug
clean_restart $testfile.x
# As `main' is not present GDB fails to find the proper inferior language.
-gdb_test_no_output "set language c++"
+set_language "c++"
# The goal is to keep the CU (Compilation Unit) unexpanded. It would be rather
# XFAIL than FAIL here. For example -readnow breaks it.
@@ -30,7 +30,7 @@ if ![runto_main] then {
return
}
-gdb_test_no_output "set language c++" ""
+set_language "c++"
gdb_test_no_output "set width 0" ""
proc do_check {name {flags ""} {show_typedefs 1} {show_methods 1} {raw 0}} {
@@ -23,7 +23,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {c++ debug}]} {
return -1
}
-gdb_test_no_output "set language c++"
+set_language "c++"
gdb_test "p *u" {You can't do that without a process to debug.} "test crash"
@@ -37,7 +37,7 @@ proc do_global_tests {lang} {
set ptypefmt "type = (class|enum|union|struct) %s $opt_underlying{.*}"
with_test_prefix $lang {
- gdb_test_no_output "set language $lang"
+ set_language "$lang"
gdb_test "ptype C" "type = class C {.*}"
gdb_test "print E" "= a"
gdb_test "ptype E" "type = enum E $opt_underlying{.*}"
@@ -102,7 +102,7 @@ with_test_prefix "in C::f" {
# Another hard-to-guess-the-users-intent bug...
# It would be really nice if we could query the user!
with_test_prefix "global collision" {
- gdb_test_no_output "set language c++"
+ set_language "c++"
setup_kfail "c++/16463" "*-*-*"
gdb_test "print global" "= 3"
@@ -270,7 +270,7 @@ proc test_info_vtbl {} {
}
proc do_tests {} {
- gdb_test_no_output "set language c++" ""
+ set_language "c++"
gdb_test_no_output "set width 0" ""
if ![runto_main] then {
@@ -139,7 +139,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \
return -1
}
-gdb_test_no_output "set language d"
+set_language "d"
if {![runto "circular1.found"]} {
return -1
@@ -18,7 +18,7 @@
if { [skip_d_tests] } { return -1 }
gdb_start
-gdb_test_no_output "set language d"
+set_language "d"
gdb_test_no_output "set debug expression 1"
# Test whether the expression debug machinery accepts the expression.
@@ -200,7 +200,7 @@ proc test_d_demangling {} {
gdb_exit
gdb_start
-if [set_lang_d] {
+if [set_language "d"] {
gdb_test_no_output "set width 0"
test_d_demangling
@@ -128,7 +128,7 @@ proc test_d_expressions {} {
gdb_exit
gdb_start
-if [set_lang_d] {
+if [set_language "d"] {
test_d_integer_literals
test_d_float_literals
test_d_expressions
@@ -54,7 +54,7 @@ proc test_builtin_d_types_accepted {} {
gdb_exit
gdb_start
-if [set_lang_d] {
+if [set_language "d"] {
test_builtin_d_types_accepted
} else {
warning "D type tests suppressed."
@@ -85,7 +85,7 @@ proc test_d_typeof {} {
gdb_exit
gdb_start
-if [set_lang_d] {
+if [set_language "d"] {
test_d_sizeof
test_d_typeof
} else {
@@ -88,7 +88,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \
return -1
}
-gdb_test_no_output "set language ada"
+set_language "ada"
gdb_test "ptype pck.table" \
"type = array \\(0 \\.\\. 4\\) of pck\\.item <packed: 6-bit elements>"
@@ -82,7 +82,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \
return -1
}
-gdb_test_no_output "set language ada"
+set_language "ada"
gdb_test "ptype pck.table" \
"type = array \\(enum_000 \\.\\. enum_128\\) of boolean"
@@ -129,7 +129,7 @@ if ![runto_main] {
return -1
}
-gdb_test_no_output "set language ada"
+set_language "ada"
# foo.three
@@ -37,7 +37,7 @@ if ![runto_main] then {
}
# main is not provided by DWARF.
-gdb_test_no_output "set language c++"
+set_language "c++"
# There are no mangled names in DWARF to suggest the v3 ABI.
gdb_test_no_output "set cp-abi gnu-v3"
@@ -39,7 +39,7 @@ if ![runto_main] then {
}
# main is not provided by DWARF.
-gdb_test_no_output "set language c++"
+set_language "c++"
# There are no mangled names in DWARF to suggest the v3 ABI.
gdb_test_no_output "set cp-abi gnu-v3"
@@ -130,7 +130,7 @@ if ![runto_main] {
return -1
}
-gdb_test_no_output "set language ada"
+set_language "ada"
# foo.three_ptr.all
@@ -65,7 +65,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \
return -1
}
-gdb_test_no_output "set language pascal"
+set_language "pascal"
gdb_test "ptype TByteArray" \
"type = array \\\[0\\.\\.191\\\] of byte"
@@ -249,7 +249,7 @@ gdb_reinitialize_dir $srcdir/$subdir
gdb_test "set print sevenbit-strings" ""
-if [set_lang_fortran] then {
+if [set_language "fortran"] then {
test_value_history
test_convenience_variables
test_integer_literals_accepted
@@ -80,7 +80,7 @@ gdb_reinitialize_dir $srcdir/$subdir
gdb_test "set print sevenbit-strings" ""
-if [set_lang_fortran] then {
+if [set_language "fortran"] then {
test_integer_literal_types_accepted
test_integer_literal_types_rejected
test_logical_literal_types_accepted
@@ -106,7 +106,7 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
-if [set_lang_go] {
+if [set_language "go"] {
test_integer_literal_types_accepted
test_logical_literal_types_accepted
test_character_literal_types_accepted
@@ -62,7 +62,7 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
-if [set_lang_go] {
+if [set_language "go"] {
test_float_accepted
test_float_rejected
} else {
@@ -63,7 +63,7 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
-if [set_lang_objc] {
+if [set_language "objective-c"] {
test_float_accepted
test_float_rejected
} else {
@@ -36,7 +36,7 @@ gdb_exit
gdb_start
# Manually switch the language to opencl
-gdb_test_no_output "set language opencl" "no prompt when setting the language to opencl"
+set_language "opencl" "no prompt when setting the language to opencl"
# Check OpenCL data types (GDB)
gdb_test "whatis bool" "type = bool"
@@ -194,8 +194,8 @@ gdb_test "whatis double16" "type = double16"
gdb_test "p sizeof(double16)" " = 128"
# Set the language back to the default: "auto; currently c"
-gdb_test_no_output "set language c" "no prompt when setting the language to c"
-gdb_test_no_output "set language auto" "no prompt when setting the language to auto"
+set_language "c" "no prompt when setting the language to c"
+set_language "auto" "no prompt when setting the language to auto"
# Load the OpenCL app
gdb_reinitialize_dir $srcdir/$subdir
@@ -63,7 +63,7 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
-if [set_lang_pascal] {
+if [set_language "pascal"] {
test_float_accepted
test_float_rejected
} else {
@@ -74,7 +74,7 @@ gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
-if [set_lang_pascal] then {
+if [set_language "pascal"] then {
test_integer_literal_types_accepted
test_logical_literal_types_accepted
test_character_literal_types_accepted
@@ -31,7 +31,7 @@ gdb_reinitialize_dir $srcdir/$subdir
if { [skip_python_tests] } { continue }
proc test_lookup_type { lang type_name } {
- gdb_test_no_output "set language ${lang}"
+ set_language "${lang}"
gdb_test "python print(gdb.lookup_type('${type_name}').name)" \
"${type_name}" \
"lookup type ${type_name} using language ${lang}"
@@ -23,7 +23,7 @@ gdb_start
gdb_test_no_output "set var \$something = 27"
-if {![set_lang_rust]} {
+if {![set_language "rust"]} {
warning "Rust expression tests suppressed."
continue
}
@@ -16,17 +16,6 @@
# Auxiliary function to set the language to D.
# The result is 1 (true) for success, 0 (false) for failure.
-proc set_lang_d {} {
- if [gdb_test_no_output "set language d"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"d\"." \
- "set language to \"d\""] {
- return 0
- }
- return 1
-}
-
# D version of runto_main.
proc d_runto_main { } {
@@ -18,17 +18,6 @@
# Auxiliary function to set the language to fortran.
# The result is 1 (true) for success, 0 (false) for failure.
-proc set_lang_fortran {} {
- if [gdb_test_no_output "set language fortran"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"fortran\"." \
- "set language to \"fortran\""] {
- return 0
- }
- return 1
-}
-
proc fortran_int4 {} {
if {[test_compiler_info {gcc-4-[012]-*}]} {
return "int4"
@@ -6018,6 +6018,47 @@ proc multi_line_input { args } {
return [join $args "\n"]
}
+# Set the language and handle possible warnings output by GDB if we select a
+# language that differs from the current frame's language.
+#
+# The first argument is the language to set.
+# The second argument is an optional message to be output by the test.
+
+proc set_language { args } {
+ global gdb_prompt
+
+ set language [lindex $args 0]
+ set command "set language $language"
+ set lang_pattern [string_to_regexp $language]
+
+ # Do we have an optional user-provided test message?
+ if {[llength $args] > 1} {
+ set message [lindex $args 1]
+ } else {
+ set message $command
+ }
+
+ # Switch to the user-selected language.
+ gdb_test_multiple $command $message {
+ -re "Undefined item: \"$lang_pattern\"\.\[\r\n\]+$gdb_prompt" {
+ fail $message
+ return 0
+ }
+ -re "Warning: the current language does not match this frame.\[\r\n\]+$gdb_prompt $" {
+ }
+ -re "$gdb_prompt $" {}
+ }
+
+ # Verify the language has been set correctly. GDB may output a warning
+ # stating the user-provided language doesn't match the frame's language.
+ # We ignore that warning for testing purposes.
+ if {$language != "auto"} {
+ if [gdb_test "show language" ".* source language is \"$lang_pattern\".*" $message] {
+ return 0
+ }
+ }
+ return 1
+}
# Always load compatibility stuff.
load_lib future.exp
@@ -19,17 +19,6 @@
# Auxiliary function to set the language to Go.
# The result is 1 (true) for success, 0 (false) for failure.
-proc set_lang_go {} {
- if [gdb_test_no_output "set language go"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"go\"." \
- "set language to \"go\""] {
- return 0
- }
- return 1
-}
-
# Go version of runto_main.
proc go_runto_main { } {
@@ -17,14 +17,3 @@
# Auxiliary function to set the language to fortran.
# The result is 1 (true) for success, 0 (false) for failure.
-
-proc set_lang_objc {} {
- if [gdb_test_no_output "set language objective-c"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"objective-c\"." \
- "set language to \"objective-c\""] {
- return 0
- }
- return 1
-}
@@ -167,17 +167,3 @@ proc gdb_compile_pascal {source destfile type options} {
return "Pascal compilation failed."
}
}
-
-# Auxiliary function to set the language to pascal.
-# The result is 1 (true) for success, 0 (false) for failure.
-
-proc set_lang_pascal {} {
- if [gdb_test_no_output "set language pascal"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"pascal\"." \
- "set language to \"pascal\""] {
- return 0
- }
- return 1
-}
@@ -15,16 +15,6 @@
# Auxiliary function to set the language to Rust.
# The result is 1 (true) for success, 0 (false) for failure.
-proc set_lang_rust {} {
- if [gdb_test_no_output "set language rust"] {
- return 0
- }
- if [gdb_test "show language" ".* source language is \"rust\"." \
- "set language to \"rust\""] {
- return 0
- }
- return 1
-}
proc gdb_compile_rust {sources dest options} {
if {[llength $sources] > 1} {