This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Fix up some races and regexps in MI tests


This patch fixes up a couple of bugs I've encountered running the MI
tests.

Most of the changes deal with not matching more than we expect.  Using
non-greedy matching would work too, but I chose to be explicit; match
the contents of line="..." with [^"]* or [^\n]* instead of .*.

I also fixed a race in mi-nonstop.exp; we can not test that info
threads reports all three threads as running, if two are about to
hit breakpoints.  If they hit the breakpoints first, then not only
will the check fail, but we'll never see the stops we expected.

Tested on x86_64-linux, checked in.  I still get failures in
mi-nonstop.exp with -m64 but they look like several different real
problems, not test problems.

-- 
Daniel Jacobowitz
CodeSourcery

2008-09-13  Daniel Jacobowitz  <dan@codesourcery.com>

	* gdb.mi/mi-nonstop.exp: Do not check thread state while a
	stop is pending.  Avoid ".*" when two stops are pending.
	* lib/gdb.exp (fullname_syntax_POSIX, fullname_syntax_UNC)
	(fullname_syntax_DOS_CASE, fullname_syntax_DOS): Do not match
	newlines in fullnames.
	* lib/mi-support.exp (mi_run_cmd): Do not require an anchor.
	(mi_expect_stop): Update comments.  Only anchor in sync mode.
	Do not match newlines.
	(mi_send_resuming_command_raw): Always return status.
	(mi_get_stop_line): Do not match more than one line by accident.
	Only anchor in sync mode.
	(mi_run_inline_test): If -exec-next fails, give up.

Index: gdb.mi/mi-nonstop.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-nonstop.exp,v
retrieving revision 1.2
diff -u -p -r1.2 mi-nonstop.exp
--- gdb.mi/mi-nonstop.exp	21 Aug 2008 15:09:42 -0000	1.2
+++ gdb.mi/mi-nonstop.exp	13 Sep 2008 16:57:57 -0000
@@ -155,9 +155,7 @@ gdb_expect {
     }
 }
 
-check_thread_states {"running" "running" "running"} "thread state, resume all"
-
-mi_expect_stop "breakpoint-hit" "break_at_me" ".*" "non-stop.c" ".*" {"" "disp=\"keep\""} "w0,i2 stop"
+mi_expect_stop "breakpoint-hit" "break_at_me" "\[^\n\]*" "non-stop.c" "\[0-9\]*" {"" "disp=\"keep\""} "w0,i2 stop"
 mi_expect_stop "breakpoint-hit" "break_at_me" ".*" "non-stop.c" ".*" {"" "disp=\"keep\""} "w1,i2 stop"
 
 # At this point, thread 1 (main) is running, and worker threads are stopped.
Index: lib/gdb.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdb.exp,v
retrieving revision 1.106
diff -u -p -r1.106 gdb.exp
--- lib/gdb.exp	4 Sep 2008 22:00:25 -0000	1.106
+++ lib/gdb.exp	13 Sep 2008 16:57:57 -0000
@@ -57,17 +57,17 @@ if ![info exists gdb_prompt] then {
 
 # The variable fullname_syntax_POSIX is a regexp which matches a POSIX 
 # absolute path ie. /foo/ 
-set fullname_syntax_POSIX "/.*/"
+set fullname_syntax_POSIX {/[^\n]*/}
 # The variable fullname_syntax_UNC is a regexp which matches a Windows 
 # UNC path ie. \\D\foo\ 
-set fullname_syntax_UNC {\\\\[^\\]+\\.+\\}
+set fullname_syntax_UNC {\\\\[^\\]+\\[^\n]+\\}
 # The variable fullname_syntax_DOS_CASE is a regexp which matches a 
 # particular DOS case that GDB most likely will output
 # ie. \foo\, but don't match \\.*\ 
-set fullname_syntax_DOS_CASE {\\[^\\].*\\}
+set fullname_syntax_DOS_CASE {\\[^\\][^\n]*\\}
 # The variable fullname_syntax_DOS is a regexp which matches a DOS path
 # ie. a:\foo\ && a:foo\ 
-set fullname_syntax_DOS {[a-zA-Z]:.*\\}
+set fullname_syntax_DOS {[a-zA-Z]:[^\n]*\\}
 # The variable fullname_syntax is a regexp which matches what GDB considers
 # an absolute path. It is currently debatable if the Windows style paths 
 # d:foo and \abc should be considered valid as an absolute path.
Index: lib/mi-support.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/mi-support.exp,v
retrieving revision 1.72
diff -u -p -r1.72 mi-support.exp
--- lib/mi-support.exp	19 Aug 2008 14:13:29 -0000	1.72
+++ lib/mi-support.exp	13 Sep 2008 16:57:57 -0000
@@ -795,7 +795,7 @@ proc mi_run_cmd {args} {
 	if [target_info exists gdb,do_reload_on_run] {
 	    send_gdb "220-exec-continue\n";
 	    gdb_expect 60 {
-		-re "220\\^running\[\r\n\]+\\*running,thread-id=\"\[^\"\]+\"\r\n$mi_gdb_prompt$" {}
+		-re "220\\^running\[\r\n\]+\\*running,thread-id=\"\[^\"\]+\"\r\n$mi_gdb_prompt" {}
 		default {}
 	    }
 	    return;
@@ -943,7 +943,10 @@ proc detect_async {} {
 # When we fail to match output at all, -1 is returned.  Otherwise,
 # the line at which we stop is returned.  This is useful when exact
 # line is not possible to specify for some reason -- one can pass
-# the .* regexp for line, and then check the line programmatically.
+# the .* or "\[0-9\]*" regexps for line, and then check the line
+# programmatically.
+#
+# Do not pass .* for any argument if you are expecting more than one stop.
 proc mi_expect_stop { reason func args file line extra test } {
 
     global mi_gdb_prompt
@@ -965,12 +968,12 @@ proc mi_expect_stop { reason func args f
     if {$async} {
         set prompt_re ""
     } else {
-        set prompt_re "$mi_gdb_prompt"
+        set prompt_re "$mi_gdb_prompt$"
     }
 
     if { $reason == "really-no-reason" } {
         gdb_expect {
-          -re "\\*stopped\r\n$prompt_re$" {
+          -re "\\*stopped\r\n$prompt_re" {
             pass "$test"
           }
           timeout {
@@ -983,7 +986,7 @@ proc mi_expect_stop { reason func args f
     if { $reason == "exited-normally" } {
 
         gdb_expect {
-          -re "\\*stopped,reason=\"exited-normally\"\r\n$prompt_re$" {
+          -re "\\*stopped,reason=\"exited-normally\"\r\n$prompt_re" {
             pass "$test"
           }
           -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
@@ -1009,13 +1012,15 @@ proc mi_expect_stop { reason func args f
 
     set a $after_reason
 
-    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=.*,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re$"
+    set any "\[^\n\]*"
+
+    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re"
     gdb_expect {
-	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=.*,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\".*$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re$" {
+	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re" {
 	    pass "$test"
             return $expect_out(2,string)
 	}
-	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=.*,frame=\{addr=\"$hex\",func=\".*\",args=\[\\\[\{\].*\[\\\]\}\],file=\".*\",fullname=\"${fullname_syntax}.*\",line=\"\[0-9\]*\"\}.*\r\n$prompt_re$" {
+	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$any\",args=\[\\\[\{\]$any\[\\\]\}\],file=\"$any\",fullname=\"${fullname_syntax}$any\",line=\"\[0-9\]*\"\}$any\r\n$prompt_re" {
             verbose -log "got $expect_out(buffer)"
 	    fail "$test (stopped at wrong place)"
 	    return -1
@@ -1402,9 +1407,11 @@ proc mi_send_resuming_command_raw {comma
             # and mi_execute_to uses mi_send_resuming_command.  If we use 'pass' here,
             # it will reset kfail, so when the actual test fails, it will be flagged
             # as real failure.
+	    return 0
         }
         -re ".*${mi_gdb_prompt}" {
             fail "$test (failed to resume)"
+	    return -1
         }
         -re "\\^error,msg=.*" {
             fail "$test (MI error)"
@@ -1444,14 +1451,14 @@ proc mi_get_stop_line {test} {
   if {$async} {
       set prompt_re ""
   } else {
-      set prompt_re "$mi_gdb_prompt"
+      set prompt_re "$mi_gdb_prompt$"
   }
 
   gdb_expect {
-      -re ".*line=\"(.*)\".*\r\n$prompt_re$" {
+      -re ".*line=\"(\[0-9\]*)\".*\r\n$prompt_re" {
           return $expect_out(1,string)
       }
-      -re ".*$mi_gdb_prompt$" {
+      -re ".*$mi_gdb_prompt" {
           fail "wait for stop ($test)"
       }
       timeout {
@@ -1535,8 +1542,10 @@ proc mi_run_inline_test { testcase } {
         # the state after the statement is executed.
 
         # Single-step past the line.
-        mi_send_resuming_command "exec-next" "$testcase: step over $line"
-        set line_now [mi_get_stop_line "$testcase: step over $line"]
+        if { [mi_send_resuming_command "exec-next" "$testcase: step over $line"] != 0 } {
+	    return -1
+	}
+	set line_now [mi_get_stop_line "$testcase: step over $line"]
 
         # We probably want to use 'uplevel' so that statements
         # have direct access to global variables that the


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]