Re: [PATCH] gdb/testsuite: work around empty substring bug in expect

Tom de Vries
2025-08-27T06:25:00Z

On 8/26/25 16:35, Andrew Burgess wrote:
> There is a bug in expect, see:
>
> https://sourceforge.net/p/expect/patches/26/
>
> which causes empty substring matches from a regexp to instead return
> the complete input buffer. To reproduce this bug, try this command:
>
> expect -c 'spawn sh -c "echo -n -e \"abc\""; \
> expect -re "(a?)(a)(bc)"; \
> puts "\n"; \
> for { set i 1 } { $i < 4 } { incr i } { \
> puts -nonewline "($i): \""; \
> puts -nonewline $expect_out($i,string); \
> puts "\"" \
> }'
>
> For a working expect the output looks like:
>
> spawn sh -c echo -n -e "abc"
> abc
>
> (1): ""
> (2): "a"
> (3): "bc"
>
> But for a broken expect the output looks like:
>
> spawn sh -c echo -n -e "abc"
> abc
>
> (1): "abc"
> (2): "a"
> (3): "bc"
>
> Notice that (1) is now returning the complete input buffer rather than
> the empty string, this is wrong.
>
> This is not the first time this bug has impacted GDB's testsuite,
> this commit seems to be working around the same problem:
>
> commit e579b537353cd91cb8fac1eaeb69901d4936766f
> Date: Sat Aug 16 20:32:37 2025 +0200
>
> [gdb/testsuite] Fix TUI tests on freebsd
>
> I recently pushed this commit:
>
> commit 3825c972a636852600b47c242826313f4b9963b8
> Date: Wed Jun 18 15:02:29 2025 +0100
>
> gdb: allow gdb.Color to work correctly with pagination
>
> Which added gdb.python/py-color-pagination.exp. Bug PR gdb/33321 was
> then created as the test was failing on some hosts. Turns out, this
> is same expect bug.
>
> The fix presented here is the same as for e579b537353cd91cb8, avoid
> using optional regexp substrings at the start of a regexp, and instead
> use two separate regexp patterns. With this change in place, the test
> now passes on all hosts.
>
> There's no change in what is being tested after this commit.
>

Hi Andrew,

thanks for digging into this.

I've tested this patch on Tumbleweed, and it fixed the problem for me there.

The patch LGTM.

Approved-By: Tom de Vries <tdevries@suse.de>

- Tom

> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33321
> ---
> .../gdb.python/py-color-pagination.exp | 36 +++++++++++++------
> 1 file changed, 25 insertions(+), 11 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.python/py-color-pagination.exp b/gdb/testsuite/gdb.python/py-color-pagination.exp
> index 3235fffe5cc..e1ca1f1ce75 100644
> --- a/gdb/testsuite/gdb.python/py-color-pagination.exp
> +++ b/gdb/testsuite/gdb.python/py-color-pagination.exp
> @@ -66,18 +66,25 @@ proc test_pagination { type mode } {
> exp_continue
> }
>
> - -re "^(${::any_color}?)(${::any_color})$::str" {
> + -re "^(${::any_color})(${::any_color})$::str" {
> # After a continuation prompt GDB will restore the previous
> # color, and then we immediately switch to a new color.
> set restored_color $expect_out(1,string)
> - if { $restored_color ne ""
> - && $restored_color ne $expected_restore_color } {
> + if { $restored_color ne $expected_restore_color } {
> set saw_bad_color_handling true
> }
> set last_color $expect_out(2,string)
> exp_continue
> }
>
> + -re "^(${::any_color})$::str" {
> + # This pattern matches printing STR in all cases that are not
> + # immediately after a pagination prompt. In this case there is
> + # a single escape sequence to set the color.
> + set last_color $expect_out(1,string)
> + exp_continue
> + }
> +
> -re "^\033\\\[${::decimal}m$::str" {
> # This catches the case where the color's escape sequence has
> # not been converted back into a full style. This indicates
> @@ -86,18 +93,25 @@ proc test_pagination { type mode } {
> exp_continue
> }
>
> - -re "^((?:\033\\\[m)?)$::pagination_prompt$" {
> + -re "^\033\\\[m$::pagination_prompt$" {
> # After a pagination prompt we expect GDB to restore the last
> # color.
> set expected_restore_color $last_color
>
> - # If we didn't see a color reset sequence then the pagination
> - # prompt will have been printed in the wrong color, this is a
> - # GDB bug.
> - set color_reset $expect_out(1,string)
> - if { $color_reset eq "" } {
> - set saw_bad_color_handling true
> - }
> + # Send '\n' to view more output.
> + send_gdb "\n"
> + exp_continue
> + }
> +
> + -re "^$::pagination_prompt$" {
> + # After a pagination prompt we expect GDB to restore the last
> + # color.
> + set expected_restore_color $last_color
> +
> + # If we didn't see a color reset sequence before the pagination
> + # prompt, then the prompt will have been printed in the wrong
> + # color, this is a GDB bug.
> + set saw_bad_color_handling true
>
> # Send '\n' to view more output.
> send_gdb "\n"
>
> base-commit: 3825c972a636852600b47c242826313f4b9963b8