Re: [RFC][gdb/testsuite] Add -lbl option in gdb_test_multiple

Tom de Vries
2020-03-01T09:08:15Z

[-- Attachment #1: Type: text/plain, Size: 2800 bytes --]

On 27-02-2020 17:02, Pedro Alves wrote:
> On 2/21/20 3:35 PM, Tom de Vries wrote:
>
>> I think we don't want to integrate -lbl in the user_code parsing, because:
>> ...
>> gdb_test_multiple "command" "testname" {
>> -re "bla" {
>> }
>> -lbl
>> }
>> ...
>> and:
>> ...
>> gdb_test_multiple "command" "testname" {
>> -lbl
>> -re "bla" {
>> }
>> }
>> ...
>> will have the same effect, which is likely to cause confusion.
>
> Well:
>
> gdb_test_multiple "command" "testname" {
> -re "bar" {
> }
> -timeout 60
> }
>
> and:
>
> gdb_test_multiple "command" "testname" {
> -timeout 60
> -re "bla" {
> }
> }
>
> also have the same effect. So there's precedent and it goes
> all the way back to expect.
>

Hm, I see.

>> [gdb/testsuite] Add -lbl option in gdb_test_multiple
>>
>> Add gdb_test_multiple option -lbl, that adds a regexp after the user code that
>> reads one line, and discards it:
>> ...
>> -re "\r\n\[^\r\n\]*(?=\r\n)" {
>> exp_continue
>> }
>> ...
>>
>> In order to be able to write:
>> ...
>> gdb_test_multiple "command" "testname" {
>> ...
>> } -lbl
>> ...
>> as opposed to having to insert the "" for the prompt_regexp arguments:
>> ...
>> gdb_test_multiple "command" "testname" {
>> ...
>> } "" -lbl
>> ...
>> rewrite the promp_regexp argument usage into:
>> ...
>> gdb_test_multiple "command" "testname" {
>> ...
>> } -prompt $prompt_regexp
>> ...
>
> Honestly, to me, this:
>
> gdb_test_multiple "command" "testname" {
> ...
> } -lbl -prompt $prompt_regexp
>
> looks a bit harder to grok than:
>
> gdb_test_multiple "command" "testname" {
> -lbl
> -prompt $prompt_regexp
> ...
> }
>
> ... because those options appear at the end, after the regexes.
>
> Alternatively, if you don't like the -lbl within the {} block, and if
> we're going to use "-" options, how about supporting them before
> the {} user code block, so that the user code block is always
> at the end? Like:
>
> gdb_test_multiple "command" "testname" -lbl {
> ...
> }
>
> gdb_test_multiple "command" "testname" -prompt $prompt_regexp {
> ...
> }
>
> That should be doable with:
>
> -proc gdb_test_multiple { command message user_code { prompt_regexp "" } } {
> +proc gdb_test_multiple { command message args } {
>
> and then walking the $args list, processing "-" arguments, and interpreting
> the first non-"-" argument as the user code block (and erroring out if there
> are more arguments). I think the gdb_test_multiple code would look quite similar
> to your patch, except that the user_code parameter would no longer be a parameter,
> instead it would be a local variable set to the first non-"-" element of $args.

Yes, I like that suggestion.

Implemented and attached below.

OK for trunk.

Thanks,
- Tom

[-- Attachment #2: 0001-gdb-testsuite-Add-lbl-option-in-gdb_test_multiple.patch --]
[-- Type: text/x-patch, Size: 8053 bytes --]

[gdb/testsuite] Add -lbl option in gdb_test_multiple

Add gdb_test_multiple option -lbl, that adds a regexp after the user code that
reads one line, and discards it:
...
-re "\r\n\[^\r\n\]*(?=\r\n)" {
exp_continue
}
...

In order to be able to write:
...
gdb_test_multiple "command" "testname" -lbl {
...
}
...
rewrite the promp_regexp argument usage into the similar:
...
gdb_test_multiple "command" "testname" -prompt $prompt_regexp {
...
}
...

Build and reg-tested on x86_64-linux.

Tested gdb.base/corefile-buildid.exp with both make targets check and
check-read1.

gdb/testsuite/ChangeLog:

2020-02-2120 Pedro Alves <palves@redhat.com>
Tom de Vries <tdevries@suse.de>

* lib/gdb.exp (gdb_test_multiple): Handle prompt_regexp option using
-prompt prefix, before user_code argument. Add -lbl option likewise.
(skip_python_tests_prompt, skip_libstdcxx_probe_tests_prompt)
(gdb_is_target_1): Add -prompt prefix and move to before user_code
argument.
* gdb.base/corefile-buildid.exp: Use -lbl option. Rewrite regexps to
have "\r\n" at start-of-line, instead of at end-of-line.

---
gdb/testsuite/gdb.base/corefile-buildid.exp | 27 ++------
gdb/testsuite/lib/gdb.exp | 98 +++++++++++++++++++----------
2 files changed, 72 insertions(+), 53 deletions(-)

diff --git a/gdb/testsuite/gdb.base/corefile-buildid.exp b/gdb/testsuite/gdb.base/corefile-buildid.exp
index b9844ee354..e24562dedb 100644
--- a/gdb/testsuite/gdb.base/corefile-buildid.exp
+++ b/gdb/testsuite/gdb.base/corefile-buildid.exp
@@ -113,17 +113,11 @@ proc check_exec_file {file} {

# Get line with "Local exec file:".
set ok 0
- gdb_test_multiple "info files" "" {
- -re "^Local exec file:\r\n" {
+ gdb_test_multiple "info files" "" -lbl {
+ -re "\r\nLocal exec file:" {
set test_name $gdb_test_name
set ok 1
}
- -re "^$gdb_prompt $" {
- fail $gdb_test_name
- }
- -re "^\[^\r\n\]*\r\n" {
- exp_continue
- }
}

if { $ok == 0 } {
@@ -132,16 +126,10 @@ proc check_exec_file {file} {

# Get subsequent line with $file.
set ok 0
- gdb_test_multiple "" $test_name {
- -re "^\[\t\ \]+`[string_to_regexp $file]'\[^\r\n\]*\r\n" {
+ gdb_test_multiple "" $test_name -lbl {
+ -re "\r\n\[\t\ \]+`[string_to_regexp $file]'\[^\r\n\]*" {
set ok 1
}
- -re "^$gdb_prompt $" {
- fail $gdb_test_name
- }
- -re "^\[^\r\n\]*\r\n" {
- exp_continue
- }
}

if { $ok == 0 } {
@@ -149,13 +137,10 @@ proc check_exec_file {file} {
}

# Skip till prompt.
- gdb_test_multiple "" $test_name {
- -re "^$gdb_prompt $" {
+ gdb_test_multiple "" $test_name -lbl {
+ -re "\r\n$gdb_prompt $" {
pass $gdb_test_name
}
- -re "^\[^\r\n\]*\r\n" {
- exp_continue
- }
}
}

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 26795d0152..ab22f24436 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -698,20 +698,22 @@ proc gdb_internal_error_resync {} {
}

-# gdb_test_multiple COMMAND MESSAGE EXPECT_ARGUMENTS PROMPT_REGEXP
+# gdb_test_multiple COMMAND MESSAGE [ -promp PROMPT_REGEXP] [ -lbl ]
+# EXPECT_ARGUMENTS
# Send a command to gdb; test the result.
#
# COMMAND is the command to execute, send to GDB with send_gdb. If
# this is the null string no command is sent.
# MESSAGE is a message to be printed with the built-in failure patterns
# if one of them matches. If MESSAGE is empty COMMAND will be used.
+# -prompt PROMPT_REGEXP specifies a regexp matching the expected prompt
+# after the command output. If empty, defaults to "$gdb_prompt $".
+# -lbl specifies that line-by-line matching will be used.
# EXPECT_ARGUMENTS will be fed to expect in addition to the standard
# patterns. Pattern elements will be evaluated in the caller's
# context; action elements will be executed in the caller's context.
# Unlike patterns for gdb_test, these patterns should generally include
# the final newline and prompt.
-# PROMPT_REGEXP is a regexp matching the expected prompt after the command
-# output. If empty, defaults to "$gdb_prompt $"
#
# Returns:
# 1 if the test failed, according to a built-in failure pattern
@@ -791,7 +793,7 @@ proc gdb_internal_error_resync {} {
# }
# }
#
-proc gdb_test_multiple { command message user_code { prompt_regexp "" } } {
+proc gdb_test_multiple { command message args } {
global verbose use_gdb_stub
global gdb_prompt pagination_prompt
global GDB
@@ -801,6 +803,26 @@ proc gdb_test_multiple { command message user_code { prompt_regexp "" } } {
upvar expect_out expect_out
global any_spawn_id

+ set line_by_line 0
+ set prompt_regexp ""
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ set arg [lindex $args $i]
+ if { $arg == "-prompt" } {
+ incr i
+ set prompt_regexp [lindex $args $i]
+ } elseif { $arg == "-lbl" } {
+ set line_by_line 1
+ } else {
+ set user_code $arg
+ break
+ }
+ }
+ if { [expr $i + 1] < [llength $args] } {
+ error "Too many arguments to gdb_test_multiple"
+ } elseif { ![info exists user_code] } {
+ error "Too few arguments to gdb_test_multiple"
+ }
+
if { "$prompt_regexp" == "" } {
set prompt_regexp "$gdb_prompt $"
}
@@ -1069,6 +1091,14 @@ proc gdb_test_multiple { command message user_code { prompt_regexp "" } } {
}
}

+ if {$line_by_line} {
+ append code {
+ -re "\r\n\[^\r\n\]*(?=\r\n)" {
+ exp_continue
+ }
+ }
+ }
+
# Now patterns that apply to any spawn id specified.
append code {
-i $any_spawn_id
@@ -1996,22 +2026,24 @@ proc skip_rust_tests {} {
proc skip_python_tests_prompt { prompt_regexp } {
global gdb_py_is_py3k

- gdb_test_multiple "python print ('test')" "verify python support" {
- -re "not supported.*$prompt_regexp" {
- unsupported "Python support is disabled."
- return 1
+ gdb_test_multiple "python print ('test')" "verify python support" \
+ -prompt "$prompt_regexp" {
+ -re "not supported.*$prompt_regexp" {
+ unsupported "Python support is disabled."
+ return 1
+ }
+ -re "$prompt_regexp" {}
}
- -re "$prompt_regexp" {}
- } "$prompt_regexp"

- gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" {
- -re "3.*$prompt_regexp" {
- set gdb_py_is_py3k 1
- }
- -re ".*$prompt_regexp" {
- set gdb_py_is_py3k 0
- }
- } "$prompt_regexp"
+ gdb_test_multiple "python print (sys.version_info\[0\])" "check if python 3" \
+ -prompt "$prompt_regexp" {
+ -re "3.*$prompt_regexp" {
+ set gdb_py_is_py3k 1
+ }
+ -re ".*$prompt_regexp" {
+ set gdb_py_is_py3k 0
+ }
+ }

return 0
}
@@ -3265,13 +3297,14 @@ proc skip_unwinder_tests {} {

proc skip_libstdcxx_probe_tests_prompt { prompt_regexp } {
set supported 0
- gdb_test_multiple "info probe" "check for stap probe in libstdc++" {
- -re ".*libstdcxx.*catch.*\r\n$prompt_regexp" {
- set supported 1
- }
- -re "\r\n$prompt_regexp" {
+ gdb_test_multiple "info probe" "check for stap probe in libstdc++" \
+ -prompt "$prompt_regexp" {
+ -re ".*libstdcxx.*catch.*\r\n$prompt_regexp" {
+ set supported 1
+ }
+ -re "\r\n$prompt_regexp" {
+ }
}
- } "$prompt_regexp"
set skip [expr !$supported]
return $skip
}
@@ -3311,15 +3344,16 @@ proc skip_compile_feature_tests {} {

proc gdb_is_target_1 { target_name target_stack_regexp prompt_regexp } {
set test "probe for target ${target_name}"
- gdb_test_multiple "maint print target-stack" $test {
- -re "${target_stack_regexp}${prompt_regexp}" {
- pass $test
- return 1
- }
- -re "$prompt_regexp" {
- pass $test
+ gdb_test_multiple "maint print target-stack" $test \
+ -prompt "$prompt_regexp" {
+ -re "${target_stack_regexp}${prompt_regexp}" {
+ pass $test
+ return 1
+ }
+ -re "$prompt_regexp" {
+ pass $test
+ }
}
- } "$prompt_regexp"
return 0
}