improve hand-call-in-threads.exp failure handling

Message ID 55ECC1CC.6000307@codesourcery.com
State New, archived
Headers

Commit Message

Sandra Loosemore Sept. 6, 2015, 10:44 p.m. UTC
  I've been looking at some apparent regressions in nios2-linux-gnu 
gdbserver testing involving gdb.threads/hand-call-in-threads.exp.  It is 
failing to stop at the breakpoint after switching to thread 2, with the 
result that all subsequent tests are timing out because we've lost the 
gdb prompt while the target is stuck running an infinite loop.  Getting 
30 more timeouts after the initial failure only slows down testing and 
doesn't provide any useful information, so we might as well just give up 
the first time.

Then I noticed that, while all these tests used to PASS, they weren't 
really working, and never have, AFAICT.  Here's an excerpt from the 
oldest archived test results I have handy (from a 2012-vintage gdb):

(gdb) PASS: gdb.threads/hand-call-in-threads.exp: hand call, thread 1
thread 2
Thread ID 2 not known.
(gdb) PASS: gdb.threads/hand-call-in-threads.exp: prepare to make hand 
call, thread 2
call hand_call()

Breakpoint 3, hand_call () at 
gdb/testsuite/gdb.threads/hand-call-in-threads.c:78
78	}
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(hand_call) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) PASS: gdb.threads/hand-call-in-threads.exp: hand call, thread 2

Looks like the breakpoint hit test only appears to PASS because the 
"thread" command was unsuccessful and we're still in thread 1.  And, the 
.exp file doesn't do anything to confirm that the "thread" command was 
successful.  Nowadays the "thread" command really does switch threads 
here, but the .exp file still doesn't verify that it worked.

This patch tightens up the handling of both failure modes.  OK to commit 
as a general testsuite robustness improvement?

This doesn't fix the broken nios2 behavior, of course.  I'm still 
scratching my head....  kernel bug or something missing from the 
gdbserver target back end?  :-S

-Sandra
  

Comments

Pedro Alves Sept. 8, 2015, 10:55 a.m. UTC | #1
On 09/06/2015 11:44 PM, Sandra Loosemore wrote:
> I've been looking at some apparent regressions in nios2-linux-gnu 
> gdbserver testing involving gdb.threads/hand-call-in-threads.exp.  It is 
> failing to stop at the breakpoint after switching to thread 2, with the 
> result that all subsequent tests are timing out because we've lost the 
> gdb prompt while the target is stuck running an infinite loop.  Getting 
> 30 more timeouts after the initial failure only slows down testing and 
> doesn't provide any useful information, so we might as well just give up 
> the first time.
> 
> Then I noticed that, while all these tests used to PASS, they weren't 
> really working, and never have, AFAICT.  Here's an excerpt from the 
> oldest archived test results I have handy (from a 2012-vintage gdb):
> 
> (gdb) PASS: gdb.threads/hand-call-in-threads.exp: hand call, thread 1
> thread 2
> Thread ID 2 not known.
> (gdb) PASS: gdb.threads/hand-call-in-threads.exp: prepare to make hand 
> call, thread 2
> call hand_call()
> 
> Breakpoint 3, hand_call () at 
> gdb/testsuite/gdb.threads/hand-call-in-threads.c:78
> 78	}
> The program being debugged stopped while in a function called from GDB.
> Evaluation of the expression containing the function
> (hand_call) will be abandoned.
> When the function is done executing, GDB will silently stop.
> (gdb) PASS: gdb.threads/hand-call-in-threads.exp: hand call, thread 2
> 
> Looks like the breakpoint hit test only appears to PASS because the 
> "thread" command was unsuccessful and we're still in thread 1.  And, the 
> .exp file doesn't do anything to confirm that the "thread" command was 
> successful.  Nowadays the "thread" command really does switch threads 
> here, but the .exp file still doesn't verify that it worked.
> 
> This patch tightens up the handling of both failure modes.  OK to commit 
> as a general testsuite robustness improvement?
> 
> This doesn't fix the broken nios2 behavior, of course.  I'm still 
> scratching my head....  kernel bug or something missing from the 
> gdbserver target back end?  :-S
> 

Looks fine to me.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
index a9b90e1..64af511 100644
--- a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
+++ b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp
@@ -84,10 +84,25 @@  set total_nr_threads [expr $NR_THREADS + 1]
 # Thread numbering in gdb is origin-1, so begin numbering at 1.
 for { set i 1 } { $i <= $total_nr_threads } { incr i } {
     set thread_nr $i
-    gdb_test "thread $thread_nr" ".*" \
+    gdb_test "thread $thread_nr" \
+	".*Switching to thread $thread_nr.*" \
 	"prepare to make hand call, thread $thread_nr"
-    gdb_test "call hand_call()" "Breakpoint 3, .*" \
-	"hand call, thread $thread_nr"
+    gdb_test_multiple "call hand_call()" "" {
+	-re "Breakpoint 3, .*$gdb_prompt $" {
+	    pass "hand call, thread $thread_nr"
+	}
+	-re "$gdb_prompt $" {
+	    fail "hand call, thread $thread_nr (got gdb prompt)"
+	}
+	timeout {
+	    # If the target fails to stop at the breakpoint, it just ends
+	    # up in an infinite loop in hand_call().  If this happens
+	    # and we have lost the GDB prompt, no further tests in
+	    # this file will work and there is no point in continuing.
+	    fail "hand call, thread $thread_nr (runaway target)"
+	    return 0
+	}
+    }
 }
 
 # Now have each hand-called function return.