Re: MI testsuite to use PTY for inferior

Bob Rossi
2005-08-19T22:27:31Z

> Funny thing is that if I run mi-console.exp alone, it usually
> (although not always) succeeds.
>
> Attached are a gdb.log for a failing run and a passing run.

OK, I've tracked down why mi-console.exp breaks. Also, I can reproduce
it. The problem is slightly difficult to fix because of race conditions
so I was hoping to get some advice from people who might have had
similar experience with the testsuite.

For MI, the mi_gdb_test function is used to test the output of a
command. Only problem is, in mi_gdb_test there is this,

gdb_expect $tmt {
...
-re "\[\r\n\]*($pattern)\[\r\n\]+$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
pass "$message"
}
set result 0
}
...
-re ".*$mi_gdb_prompt\[ \]*$" {
if ![string match "" $message] then {
fail "$message"
}
set result 1
}
...
}

So, if the pattern the user passes in matches the regex, then a pass
will get put out. However, if the pattern does not match, and a
mi_gdb_prompt is reached, then a fail will be issued. Only difference
is, the second case does not have to wait the full $tmt (which is 60 in
this case) seconds to complete the match.

So, the first problem is that $pattern can not consist of more than a
single gdb prompt output. In MI this means, you send,
47-exec-next
and get back
47^running^M
(gdb) ^M
47*stopped,reason="end-stepping-range",thread-id="0",frame={addr="0x080483e8",func="main",args=[],file
(gdb) ^M

You can not expect to get back both of those in a single mi_gdb_test
command list so,
mi_gdb_test "47-exec-next" \
"47\\^running\[\r\n\]+${mi_gdb_prompt}47\\*stopped.*}" \
"Testing console output" \
"Hello \\\\\"!\[\r\n\]+"

With that in mind, the next obvious solution, which is the one used, is
to do what is currently in mi-console.exp,

mi_gdb_test "47-exec-next" \
"47\\^running" \
"Testing console output" \
"Hello \\\\\"!\[\r\n\]+"

gdb_expect {
-re "47\\*stopped.*$mi_gdb_prompt$" {
pass "Finished step over hello"
}
timeout {
fail "Finished step over hello (timeout)"
}
}

This splits up the regex matching into 2 commands, which makes sense.
The problem is, in mi_gdb_test when it goes to match 47\\^running, it is
possible that either just that has been outputted by GDB (Yay, match!),
or that also the 47\\*stopped... output has also been output by GDB. In
this case, the testcase fails because the regex in mi_gdb_test does not
match the 'end anchor' of the output from GDB. Thus the race condition.

I'm still thinking of ways to fix this without totally hacking the
testsuite, any ideas?

To reproduce this problem, put 'sleep 1' just before the gdb_expect line
in mi-support.exp:mi_gdb_test. That gives GDB enough time to output
both items that need to be matched.

Thanks,
Bob Rossi