[pushed] sss-bp-on-user-bp-2.exp sometimes fails on native GNU/Linux. (was: [pushed] PR breakpoints/17000: user breakpoint not inserted if software-single-step at same location - another test)

Message ID 539210E5.60000@redhat.com
State Committed
Headers

Commit Message

Pedro Alves June 6, 2014, 7:05 p.m. UTC
  On 06/03/2014 02:08 PM, Pedro Alves wrote:
> On 06/03/2014 12:53 PM, Pedro Alves wrote:
> 
>> (gdb) PASS: gdb.base/sss-bp-on-user-bp-2.exp: define stepi_del_break
>> stepi_del_break
>> Cannot execute this command while the target is running.
>> (gdb) FAIL: gdb.base/sss-bp-on-user-bp-2.exp: stepi_del_break
>>
>> The error is because GDB tried to remove the breakpoint from
>> memory while the thread was running, and we can't talk to the
>> server in the all-stop RSP until we get a stop reply, but in any
>> case, GDB shouldn't even be attempting to remove the breakpoint,
>> exactly because there was a sss breakpoint at the same address.
>>
>> I've added a kfail, and pushed it.
> 
> Gosh, so many different mode combinations...  So the fix for
> PR17000 doesn't fix that failure when testing against gdbserver
> _and_ hardware stepping.  Well, of course it doesn't, because in
> that case GDB will really try to remove the breakpoint, because
> there's no overlapping software single-step breakpoint.
> 

and ... 

> +# With the all-stop RSP, we can't talk to the target while it's
> +# running, until we get back the stop reply.  If not using single-step
> +# breakpoints, then the "del" in stepi_del_break below will try to
> +# delete the user breakpoint from the target, which will fail, with
> +# "Cannot execute this command while the target is running.".  On
> +# software single-step targets, that del shouldn't trigger any RSP
> +# traffic.  Just skip the test if testing against a remove target and
> +# not using software single-stepping.  IOW, skip the test if we see a
> +# 'vCont;s' or 's' in the RSP traffic.

... this is still not sufficient...

I pushed the commit below to skip the test on native targets too.

I was surprised the failure to remove the breakpoint mentioned
below didn't cause a warning.  That'll be the subject of a
separate patch.

8<-----------
From 829155c9adb5f3750c9c612702fdbf26fa7c558e Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 6 Jun 2014 19:59:21 +0100
Subject: [PATCH] sss-bp-on-user-bp-2.exp sometimes fails on native GNU/Linux.

I noticed that sss-bp-on-user-bp-2.exp is racy on native GNU/Linux.  I
sometimes still see an int3 in the disassembly:

 (gdb) PASS: gdb.base/sss-bp-on-user-bp-2.exp: set debug target 0
 disassemble test
 Dump of assembler code for function test:
    0x0000000000400590 <+0>:     push   %rbp
    0x0000000000400591 <+1>:     mov    %rsp,%rbp
    0x0000000000400594 <+4>:     nop
 => 0x0000000000400595 <+5>:     int3
    0x0000000000400596 <+6>:     pop    %rbp
    0x0000000000400597 <+7>:     retq
 End of assembler dump.
 (gdb) FAIL: gdb.base/sss-bp-on-user-bp-2.exp: before/after disassembly matches

Enabling infrun/target debug logs, we can see the problem.
Simplified, that's:

 (gdb) PASS: gdb.base/sss-bp-on-user-bp-2.exp: define stepi_del_break
 stepi_del_break
 infrun: clear_proceed_status_thread (process 25311)
 infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 25311] at 0x400594
 LLR: PTRACE_SINGLESTEP process 25311, 0 (resume event thread)
 target_resume (25311, step, 0)
 native:target_xfer_partial (3, (null), 0x0, 0x32dce4c, 0x400595, 1) = 0, 0
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 (gdb) linux_nat_wait: [process -1], [TARGET_WNOHANG]

0x400595 is the address of the breakpoint, and "= 0" is
TARGET_XFER_EOF.  That's default_memory_remove_breakpoint trying to
remove the breakpoint, but failing.

The problem is that we had just resumed the target and the native
GNU/Linux target can't read memory off of a running thread.  Most of
the time, we get "lucky", because we manage to read memory before the
kernel actually schedules the target to run.

So just give up and skip the test on any target that uses hardware
stepping, not just remote targets.

gdb/testsuite/
2014-06-06  Pedro Alves  <palves@redhat.com>

	* gdb.base/sss-bp-on-user-bp-2.exp: Look for target_resume(step)
	in target debug output instead of looking at RSP packets,
	disabling the test on any target that uses hardware stepping.
	Update comments.
---
 gdb/testsuite/ChangeLog                        |  7 ++++++
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp | 31 ++++++++++++--------------
 2 files changed, 21 insertions(+), 17 deletions(-)
  

Comments

Pedro Alves June 9, 2014, 2:26 p.m. UTC | #1
On 06/06/2014 08:05 PM, Pedro Alves wrote:

> Enabling infrun/target debug logs, we can see the problem.
> Simplified, that's:
> 
>  (gdb) PASS: gdb.base/sss-bp-on-user-bp-2.exp: define stepi_del_break
>  stepi_del_break
>  infrun: clear_proceed_status_thread (process 25311)
>  infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 25311] at 0x400594
>  LLR: PTRACE_SINGLESTEP process 25311, 0 (resume event thread)
>  target_resume (25311, step, 0)
>  native:target_xfer_partial (3, (null), 0x0, 0x32dce4c, 0x400595, 1) = 0, 0
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  (gdb) linux_nat_wait: [process -1], [TARGET_WNOHANG]
> 
> 0x400595 is the address of the breakpoint, and "= 0" is
> TARGET_XFER_EOF.  That's default_memory_remove_breakpoint trying to
> remove the breakpoint, but failing.

I was quite surprised this didn't result in a user visible warning.
Turns out that's a regression compared to 7.7.  This fixes it:

 https://sourceware.org/ml/gdb-patches/2014-06/msg00377.html
  

Patch

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 933df0a..327e648 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,12 @@ 
 2014-06-06  Pedro Alves  <palves@redhat.com>
 
+	* gdb.base/sss-bp-on-user-bp-2.exp: Look for target_resume(step)
+	in target debug output instead of looking at RSP packets,
+	disabling the test on any target that uses hardware stepping.
+	Update comments.
+
+2014-06-06  Pedro Alves  <palves@redhat.com>
+
 	* gdb.base/break-unload-file.exp: Fix typo.
 
 2014-06-06  Yao Qi  <yao@codesourcery.com>
diff --git a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
index 87fa5f8..a196f68 100644
--- a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
+++ b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
@@ -50,23 +50,20 @@  delete_breakpoints
 # delete the user breakpoint from the target, which will fail, with
 # "Cannot execute this command while the target is running.".  On
 # software single-step targets, that del shouldn't trigger any RSP
-# traffic.  Just skip the test if testing against a remove target and
-# not using software single-stepping.  IOW, skip the test if we see a
-# 'vCont;s' or 's' in the RSP traffic.
-
-gdb_test_no_output "set debug remote 1"
-
-set rsp_hardware_step 0
+# traffic.  Hardware-step targets that can't access memory while the
+# target is running, either remote or native, are likewise affected.
+# So we just skip the test if not using software single-stepping.  We
+# detect that by looking for 'target_resume (..., step)' in "debug
+# target" output.
 
 # Probe for software single-step breakpoint use.
-set test "probe RSP hardware step"
+
+gdb_test_no_output "set debug target 1"
+set hardware_step 0
+set test "probe target hardware step"
 gdb_test_multiple "si" $test {
-    -re "\\\$vCont;s.*$gdb_prompt $" {
-	set rsp_hardware_step 1
-	pass $test
-    }
-    -re "\\\$s#.*$gdb_prompt $" {
-	set rsp_hardware_step 1
+    -re "target_resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
+	set hardware_step 1
 	pass $test
     }
     -re "$gdb_prompt $" {
@@ -74,12 +71,12 @@  gdb_test_multiple "si" $test {
     }
 }
 
-if { $rsp_hardware_step } {
-    unsupported "remote target doesn't use software single-stepping"
+if { $hardware_step } {
+    unsupported "target doesn't use software single-stepping"
     return
 }
 
-gdb_test_no_output "set debug remote 0"
+gdb_test_no_output "set debug target 0"
 
 set line_re "\[^\r\n\]*"