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]

Re: [RFC] PR 15075 dprintf interferes with "next"


On 06/25/13 04:20, Pedro Alves wrote:
On 06/24/2013 05:24 AM, Hui Zhu wrote:

Hmm, this still looks racy to me, even on native targets.
"continue &" produces a gdb prompt.  gdb_test_multiple
inside has a match for the prompt:

	-re "\r\n$gdb_prompt $" {
	    if ![string match "" $message] then {
		fail "$message"
	    }
	    set result 1
	}

So if the expect happens to read

continue &
(gdb)

from the buffer, we'll hit the fail.  Doesn't the read1 hack catch this?

EXPECT=../contrib/expect-read1.sh make check RUNTESTFLAGS="dprintf-non-stop.exp" is OK in my part.

I suspect the "exec sleep 1" is masking it.  If you remove the sleep,
then the test fails.



We need to consume the prompt after that "continue&".

+    }
+}
+
+set test "inferior stopped"
+gdb_test_multiple "" $test {
+    -re "\r\n\\\[.* \[0-9\]+\\\] #1 stopped\\\.\r\n" {
+	pass $test
+    }
+}

Likewise?


I just copy this part of code from "gdb.base/async-shell.exp".
Could you give me some help about how to consume the prompt after that "continue&"?

Just doing:

  -send_gdb "continue &\n"
  +gdb_test "continue &" "Continuing\\."

will consume the prompt.  Otherwise, we'd do like
e.g., completion.exp does:

		# Eat the prompt
		gdb_expect {
		    -re "$gdb_prompt " {
			pass "$test (eat prompt)"
		    }
		    timeout {
			fail "(timeout) $test (eat prompt)"
		    }
		}

We still need the sleep, but for different a reason -- be sure
to wait for the dprintf to trigger -- we need GDB to print the
prompt before the program reaches the dprintf.  I think it's slightly
better to do the sleep on the inferior program side.  We can expect
the "At foo entry" output from the dprintf, as the default "set dprintf-style"
is "gdb".

I see now that the

set test "inferior stopped"
gdb_test_multiple "" $test {
     -re "\r\n\\\[.* \[0-9\]+\\\] #1 stopped\\\.\r\n" {
	pass $test
     }
}

case doesn't need to eat the prompt, as that output appears
after the prompt:

(gdb) PASS: gdb.base/dprintf-non-stop.exp: continue &
At foo entry
PASS: gdb.base/dprintf-non-stop.exp: dprintf triggered
interrupt
(gdb)
[process 6106] #1 stopped.
PASS: gdb.base/dprintf-non-stop.exp: interrupt
PASS: gdb.base/dprintf-non-stop.exp: inferior stopped

and the "interrupt" test already eats it.

See patchlet on top of yours below.  Please merge it with
yours, and push the result in (and post it, for the archives).

Hi Pedro,

Thanks for your patch.

I merged it with old patch together.

Please help me review it.

Thanks,
Hui

2013-06-25  Yao Qi  <yao@codesourcery.com>
	    Hui Zhu  <hui@codesourcery.com>
	    Pedro Alves  <palves@redhat.com>

	PR breakpoints/15075
	PR breakpoints/15434
	* breakpoint.c (bpstat_stop_status): Call
	b->ops->after_condition_true.
	(update_dprintf_command_list): Don't append "continue" command
	to the command list of dprintf breakpoint.
	(base_breakpoint_after_condition_true): New function.
	(base_breakpoint_ops): Add base_breakpoint_after_condition_true.
	(dprintf_after_condition_true): New function.
	(initialize_breakpoint_ops): Set dprintf_after_condition_true.
	* breakpoint.h (breakpoint_ops): Add after_condition_true.

2013-06-25  Yao Qi  <yao@codesourcery.com>
	    Hui Zhu  <hui@codesourcery.com>
	    Pedro Alves  <palves@redhat.com>

	PR breakpoints/15075
	PR breakpoints/15434
	* gdb.base/dprintf-next.c: New file.
	* gdb.base/dprintf-next.exp: New file.
	* gdb.base/dprintf-non-stop.c: New file.
	* gdb.base/dprintf-non-stop.exp: New file.
	* gdb.base/dprintf.exp: Don't check "continue" in the output
	of "info breakpoints".
	* gdb.mi/mi-breakpoint-changed.exp (test_insert_delete_modify):
	Don't check "continue" in script field.


Thanks,
Pedro Alves

---
  gdb/testsuite/gdb.base/dprintf-non-stop.c   |  1 +
  gdb/testsuite/gdb.base/dprintf-non-stop.exp | 17 +++++++++++++++--
  2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.base/dprintf-non-stop.c b/gdb/testsuite/gdb.base/dprintf-non-stop.c
index 2198848..2d25d9e 100644
--- a/gdb/testsuite/gdb.base/dprintf-non-stop.c
+++ b/gdb/testsuite/gdb.base/dprintf-non-stop.c
@@ -23,6 +23,7 @@ foo ()
  int
  main ()
  {
+  sleep (1);
    foo ();
    sleep (3);
    return 0;
diff --git a/gdb/testsuite/gdb.base/dprintf-non-stop.exp b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
index c3fb85e..707f913 100644
--- a/gdb/testsuite/gdb.base/dprintf-non-stop.exp
+++ b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
@@ -36,9 +36,22 @@ if ![runto main] {

  gdb_test "dprintf foo,\"At foo entry\\n\"" "Dprintf .*"

-send_gdb "continue &\n"
-exec sleep 1
+gdb_test "continue &" "Continuing\\."

+# Wait for the dprintf to trigger.
+set test "dprintf triggered"
+gdb_expect {
+    -re "At foo entry" {
+	pass "$test"
+    }
+    timeout {
+	fail "$test (timeout)"
+    }
+}
+
+# Now test that we're still able to issue commands.  GDB used to
+# implement re-resuming from dprintfs with a synchronous "continue" in
+# the dprintf's command list, which stole the prompt from the user.
  set test "interrupt"
  gdb_test_multiple $test $test {
      -re "interrupt\r\n$gdb_prompt " {


Attachment: dprintf-continue.txt
Description: Text document

Attachment: dprintf-continue-test.txt
Description: Text document


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