public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/8] Refactor gdb.base/disp-step-syscall.exp for general step over test
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
  2016-02-19 14:36 ` [PATCH 4/8] Step over syscalll insn with disp-step on and off Yao Qi
@ 2016-02-19 14:36 ` Yao Qi
  2016-02-19 14:36 ` [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver Yao Qi
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:36 UTC (permalink / raw)
  To: gdb-patches

This patch moves some code out of disp_step_cross_syscall to a new proc
check_pc_after_cross_syscall, and delete the breakpoint later.

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp (check_pc_after_cross_syscall): New
	proc.
	(disp_step_cross_syscall): Move code to check_pc_after_cross_syscall
	and delete breakpoint later.
---
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 80cdc3b..aba5db8 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -32,6 +32,18 @@ if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
     return -1
 }
 
+proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
+    set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
+
+    set test "single step over $syscall final pc"
+    if {$syscall_insn_next_addr != 0
+	&& $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
+	pass $test
+    } else {
+	fail $test
+    }
+}
+
 proc disp_step_cross_syscall { syscall } {
     with_test_prefix "$syscall" {
 	global syscall_insn
@@ -120,7 +132,6 @@ proc disp_step_cross_syscall { syscall } {
 		pass "break on syscall insns"
 	    }
 	}
-	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
 
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
 	    "continue to syscall insn $syscall"
@@ -132,19 +143,13 @@ proc disp_step_cross_syscall { syscall } {
 	    return -1
 	}
 
-	set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
-
-	set test "single step over $syscall final pc"
-	if {$syscall_insn_next_addr != 0
-	    && $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
-	    pass $test
-	} else {
-	    fail $test
-	}
+	check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
 
 	# Delete breakpoint syscall insns to avoid interference to other syscalls.
 	gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn"
 
+	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
+
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
 	    "continue to marker ($syscall)"
     }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (2 preceding siblings ...)
  2016-02-19 14:36 ` [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver Yao Qi
@ 2016-02-19 14:36 ` Yao Qi
  2016-02-25 17:28   ` Pedro Alves
  2016-02-19 14:37 ` [PATCH 6/8] Reformat disp-step-syscall.exp Yao Qi
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:36 UTC (permalink / raw)
  To: gdb-patches

We can call fork/vfork more easily in the test.

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-fork.c (main): Use loop.
	* gdb.base/disp-step-vfork.c (main): Likewise.
---
 gdb/testsuite/gdb.base/disp-step-fork.c  | 35 ++++++--------------
 gdb/testsuite/gdb.base/disp-step-vfork.c | 55 ++++++++++----------------------
 2 files changed, 26 insertions(+), 64 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c
index dd84f57..c8f2cf9 100644
--- a/gdb/testsuite/gdb.base/disp-step-fork.c
+++ b/gdb/testsuite/gdb.base/disp-step-fork.c
@@ -24,33 +24,18 @@ marker () {}
 int
 main (void)
 {
-  int  pid;
+  int i, pid;
 
-  pid = fork ();
-  if (pid == 0) /* child */
-    {
-      exit (0); /* at exit */
-    }
-  else
-    {
-    }
-
-  pid = fork ();
-  if (pid == 0) /* child */
-    {
-      exit (0); /* at exit */
-    }
-  else
-    {
-    }
-
-  pid = fork ();
-  if (pid == 0) /* child */
-    {
-      exit (0); /* at exit */
-    }
-  else
+  for (i = 0; i < 3; i++)
     {
+      pid = fork ();
+      if (pid == 0) /* child */
+	{
+	  exit (0); /* at exit */
+	}
+      else
+	{
+	}
     }
 
   marker ();
diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/disp-step-vfork.c
index dfc75af..0ae725b 100644
--- a/gdb/testsuite/gdb.base/disp-step-vfork.c
+++ b/gdb/testsuite/gdb.base/disp-step-vfork.c
@@ -23,45 +23,22 @@ marker () {}
 int
 main (void)
 {
-  int pid;
-
-  pid = vfork ();
-  if (pid == -1)
-    {
-      return 1;
-    }
-  else if (pid != 0)
-    {
-    }
-  else
-    {
-      _exit (0);
-    }
-
-  pid = vfork ();
-  if (pid == -1)
-    {
-      return 1;
-    }
-  else if (pid != 0)
-    {
-    }
-  else
-    {
-      _exit (0);
-    }
-
-  pid = vfork ();
-  if (pid == -1)
-    {
-      return 1;
-    }
-  else if (pid != 0)
-    {
-    }
-  else
-    {
-      _exit (0);
+  int i, pid;
+
+  for (i = 0; i < 3; i++)
+    {
+      pid = vfork ();
+      if (pid == -1)
+	{
+	  return 1;
+	}
+      else if (pid != 0)
+	{
+	}
+      else
+	{
+	  _exit (0);
+	}
     }
 
   marker ();
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
  2016-02-19 14:36 ` [PATCH 4/8] Step over syscalll insn with disp-step on and off Yao Qi
  2016-02-19 14:36 ` [PATCH 2/8] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
@ 2016-02-19 14:36 ` Yao Qi
  2016-02-23 20:28   ` Luis Machado
  2016-02-25 17:31   ` Pedro Alves
  2016-02-19 14:36 ` [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c Yao Qi
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:36 UTC (permalink / raw)
  To: gdb-patches

We can also extend disp-step-syscall.exp to test GDBserver step over
breakpoint on syscall instruction.  That is, we set a breakpoint
with a false condition on syscall instruction, so that GDBserver will
step over it.

This test triggers a GDBserver internal error, which can be fixed by
this series.

(gdb) PASS: gdb.base/disp-step-syscall.exp: fork: break cond on target: break on syscall insns
continue^M
Continuing.^M
Remote connection closed^M
(gdb) FAIL: gdb.base/disp-step-syscall.exp: fork: break cond on target: continue to fork again

In GDBserver, there is an internal error,

/home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
unsuspend LWP 25554, suspended=-1

the simplified reproducer is like,

$ ./gdb ./testsuite/outputs/gdb.base/disp-step-syscall/disp-step-fork
(gdb) b main
(gdb) c
(gdb) disassemble fork // in order to find the address of insn 'syscall'
....
   0x00007ffff7ad6023 <+179>:	syscall
(gdb) b *0x00007ffff7ad6023 if main == 0
(gdb) c

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-fork.c (main): Increase loop boundary.
	* gdb.base/disp-step-vfork.c (main): Likewise.
	* gdb.base/disp-step-syscall.exp (disp_step_cross_syscall): Test
	breakpoint condition evaluated on the target side.
---
 gdb/testsuite/gdb.base/disp-step-fork.c      |  2 +-
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 38 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/disp-step-vfork.c     |  2 +-
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c
index d8d602f..6d477ea 100644
--- a/gdb/testsuite/gdb.base/disp-step-fork.c
+++ b/gdb/testsuite/gdb.base/disp-step-fork.c
@@ -26,7 +26,7 @@ main (void)
 {
   int i, pid;
 
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 6; i++)
     {
       pid = fork ();
       if (pid == 0) /* child */
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 9e43fbb..53ac1e1 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -153,6 +153,44 @@ proc disp_step_cross_syscall { syscall } {
     }
 	}
 
+	with_test_prefix "break cond on target" {
+	    set cond_bp_target 1
+
+	    set test "set breakpoint condition-evaluation target"
+	    gdb_test_multiple $test $test {
+		-re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
+		    # Target doesn't support breakpoint condition
+		    # evaluation on its side.
+		    set cond_bp_target 0
+		}
+		-re "^$test\r\n$gdb_prompt $" {
+		}
+	    }
+
+	    if { $cond_bp_target } {
+		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall"
+
+		# Create a breakpoint with the condition which is false.
+		set syscall_insn_bp 0
+		gdb_test_multiple "break \*$syscall_insn_addr if main == 0" \
+		    "break on syscall insns" {
+			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+			    set syscall_insn_bp $expect_out(1,string)
+			    pass "break on syscall insns"
+			}
+		    }
+
+		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall again"
+
+		# Delete breakpoint syscall insns to avoid interference to
+		# other syscalls.
+		gdb_test_no_output "delete $syscall_insn_bp" \
+		    "delete break $syscall insn"
+	    }
+	}
+
 	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
 
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/disp-step-vfork.c
index 17bef55..35665ab 100644
--- a/gdb/testsuite/gdb.base/disp-step-vfork.c
+++ b/gdb/testsuite/gdb.base/disp-step-vfork.c
@@ -25,7 +25,7 @@ main (void)
 {
   int i, pid;
 
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < 6; i++)
     {
       pid = vfork ();
       if (pid == -1)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/8] Step over syscalll insn with disp-step on and off
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
@ 2016-02-19 14:36 ` Yao Qi
  2016-02-25 17:27   ` Pedro Alves
  2016-02-19 14:36 ` [PATCH 2/8] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:36 UTC (permalink / raw)
  To: gdb-patches

disp-step-syscall.exp was added to test displaced stepping over syscall
instructions, in which we set breakpoint on syscall instruction, and
step over it.  In fact, we can extend the test to non-displaced-stepping
case.  This patch wraps the test with displaced stepping on and off.
Note that the indentation and format isn't adjusted here to make this
patch easy to read.  The following patch will fix the format separately.

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-fork.c (main): Increase loop boundary.
	* gdb.base/disp-step-vfork.c (main): Likewise.
	* gdb.base/disp-step-syscall.exp: Don't invoke
	support_displaced_stepping.
	(disp_step_cross_syscall): Test with displaced stepping off and
	on if supported.
---
 gdb/testsuite/gdb.base/disp-step-fork.c      |  2 +-
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 17 +++++++++++------
 gdb/testsuite/gdb.base/disp-step-vfork.c     |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c
index c8f2cf9..d8d602f 100644
--- a/gdb/testsuite/gdb.base/disp-step-fork.c
+++ b/gdb/testsuite/gdb.base/disp-step-fork.c
@@ -26,7 +26,7 @@ main (void)
 {
   int i, pid;
 
-  for (i = 0; i < 3; i++)
+  for (i = 0; i < 4; i++)
     {
       pid = fork ();
       if (pid == 0) /* child */
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index aba5db8..9e43fbb 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -15,11 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-if { ![support_displaced_stepping] } {
-    unsupported "displaced stepping"
-    return -1
-}
-
 set syscall_insn ""
 
 # Define the syscall instruction for each target.
@@ -119,6 +114,14 @@ proc disp_step_cross_syscall { syscall } {
 	}
 	set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"]
 
+	set disp_step_opts { "off" }
+	if { [support_displaced_stepping] } {
+	    lappend disp_step_opts "on"
+	}
+
+	foreach displaced $disp_step_opts {
+	    with_test_prefix "displaced $displaced" {
+
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
 	    "continue to $syscall (3rd time)"
 
@@ -136,7 +139,7 @@ proc disp_step_cross_syscall { syscall } {
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
 	    "continue to syscall insn $syscall"
 
-	gdb_test_no_output "set displaced-stepping on"
+	gdb_test_no_output "set displaced-stepping $displaced"
 
 	# Check the address of next instruction of syscall.
 	if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
@@ -147,6 +150,8 @@ proc disp_step_cross_syscall { syscall } {
 
 	# Delete breakpoint syscall insns to avoid interference to other syscalls.
 	gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn"
+    }
+	}
 
 	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
 
diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/disp-step-vfork.c
index 0ae725b..17bef55 100644
--- a/gdb/testsuite/gdb.base/disp-step-vfork.c
+++ b/gdb/testsuite/gdb.base/disp-step-vfork.c
@@ -25,7 +25,7 @@ main (void)
 {
   int i, pid;
 
-  for (i = 0; i < 3; i++)
+  for (i = 0; i < 4; i++)
     {
       pid = vfork ();
       if (pid == -1)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/8] Leave child suspended when step over parent
@ 2016-02-19 14:36 Yao Qi
  2016-02-19 14:36 ` [PATCH 4/8] Step over syscalll insn with disp-step on and off Yao Qi
                   ` (8 more replies)
  0 siblings, 9 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:36 UTC (permalink / raw)
  To: gdb-patches

When I teach GDBserver on arm-linux handling single step requested by
GDB (via vCont;s), I see a GDBserver internal error.  I can also
reproduce this internal error on mainline GDBserver as well.  In short,
the internal error is triggered by the child's incorrect suspend count,
because it is spawned by the parent and GDBserver is stepping the
parent over a breakpoint.  See more in patch #1.

Patches #2 to #8 are about refactoring and extending test case to
reproduce the internal error I've see.

Regression tested on x86_64-linux.

*** BLURB HERE ***

Yao Qi (8):
  [GDBserver] Leave child suspended when step over parent
  Refactor gdb.base/disp-step-syscall.exp for general step over test
  Use loop in disp-step-fork.c and disp-step-vfork.c
  Step over syscalll insn with disp-step on and off
  Step over fork/vfork syscall insn in gdbserver
  Reformat disp-step-syscall.exp
  Rename disp-step-syscall.exp to step-over-syscall.exp
  New test about step over clone syscall

 gdb/gdbserver/linux-low.c                    |  14 +-
 gdb/testsuite/gdb.base/disp-step-fork.c      |  58 -------
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 154 ------------------
 gdb/testsuite/gdb.base/disp-step-vfork.c     |  70 ---------
 gdb/testsuite/gdb.base/step-over-clone.c     |  53 +++++++
 gdb/testsuite/gdb.base/step-over-fork.c      |  43 +++++
 gdb/testsuite/gdb.base/step-over-syscall.exp | 225 +++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/step-over-vfork.c     |  47 ++++++
 8 files changed, 377 insertions(+), 287 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-fork.c
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-syscall.exp
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-vfork.c
 create mode 100644 gdb/testsuite/gdb.base/step-over-clone.c
 create mode 100644 gdb/testsuite/gdb.base/step-over-fork.c
 create mode 100644 gdb/testsuite/gdb.base/step-over-syscall.exp
 create mode 100644 gdb/testsuite/gdb.base/step-over-vfork.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/8] [GDBserver] Leave child suspended when step over parent
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (4 preceding siblings ...)
  2016-02-19 14:37 ` [PATCH 6/8] Reformat disp-step-syscall.exp Yao Qi
@ 2016-02-19 14:37 ` Yao Qi
  2016-02-23 20:23   ` Luis Machado
  2016-02-25 17:12   ` Pedro Alves
  2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
                   ` (2 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:37 UTC (permalink / raw)
  To: gdb-patches

I see the following GDBserver internal error in two cases,

 gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
 unsuspend LWP 17200, suspended=-1

 1. step over a breakpoint on fork/vfork syscall instruction,
 2. step over a breakpoint on clone syscall instruction and child
    threads hits a breakpoint,

the stack backtrace is

 #0  internal_error (file=file@entry=0x44c4c0 "gdb/gdbserver/linux-low.c", line=line@entry=1922,
    fmt=fmt@entry=0x44c7d0 "unsuspend LWP %ld, suspended=%d\n") at gdb/gdbserver/../common/errors.c:51
 #1  0x0000000000424014 in lwp_suspended_decr (lwp=<optimised out>, lwp=<optimised out>) at gdb/gdbserver/linux-low.c:1922
 #2  0x000000000042403a in unsuspend_one_lwp (entry=<optimised out>, except=0x66e8c0) at gdb/gdbserver/linux-low.c:2885
 #3  0x0000000000405f45 in find_inferior (list=<optimised out>, func=func@entry=0x424020 <unsuspend_one_lwp>, arg=arg@entry=0x66e8c0)
    at gdb/gdbserver/inferiors.c:243
 #4  0x00000000004297de in unsuspend_all_lwps (except=0x66e8c0) at gdb/gdbserver/linux-low.c:2895
 #5  linux_wait_1 (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, target_options=target_options@entry=0)
    at gdb/gdbserver/linux-low.c:3632
 #6  0x000000000042a764 in linux_wait (ptid=..., ourstatus=0x665ec0 <last_status>, target_options=0)
    at gdb/gdbserver/linux-low.c:3770
 #7  0x0000000000411163 in mywait (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, options=options@entry=0, connected_wait=connected_wait@entry=1)
    at gdb/gdbserver/target.c:214
 #8  0x000000000040b1f2 in resume (actions=0x66f800, num_actions=1) at gdb/gdbserver/server.c:2757
 #9  0x000000000040f660 in handle_v_cont (own_buf=0x66a630 "vCont;c:p45e9.-1") at gdb/gdbserver/server.c:2719

when GDBserver steps over a thread, other threads have been suspended,
the "stepping" thread may create new thread, but GDBserver doesn't set
it suspend count to 1.  When GDBserver unsuspend threads, the child's
suspend count goes to -1, and the assert is triggered.  In fact, GDBserver
has already taken care of suspend count of new thread when GDBserver is
suspending all threads except the one GDBserver wants to step over by
https://sourceware.org/ml/gdb-patches/2015-07/msg00946.html

+	  /* If we're suspending all threads, leave this one suspended
+	     too.  */
+	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+	    {
+	      if (debug_threads)
+		debug_printf ("HEW: leaving child suspended\n");
+	      child_lwp->suspended = 1;
+	    }

but that is not enough, because new thread can be still spawned in
the thread which is being stepped over.  This patch extends the
condition that GDBserver set child's suspend count to one if it is
suspending threads or stepping over the thread.

gdb/gdbserver:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* linux-low.c (handle_extended_wait): Set child suspended
	if event_lwp->bp_reinsert isn't zero.
---
 gdb/gdbserver/linux-low.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3f085fd..3765e08 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -529,8 +529,10 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 	  child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
 
 	  /* If we're suspending all threads, leave this one suspended
-	     too.  */
-	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+	     too.  If we're stepping over the parent, all other threads
+	     have been suspended already, leave this one suspended too.  */
+	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
+	      || event_lwp->bp_reinsert != 0)
 	    {
 	      if (debug_threads)
 		debug_printf ("HEW: leaving child suspended\n");
@@ -583,9 +585,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 	 before calling linux_resume_one_lwp.  */
       new_lwp->stopped = 1;
 
-     /* If we're suspending all threads, leave this one suspended
-	too.  */
-      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+      /* If we're suspending all threads, leave this one suspended
+	 too.  If we're stepping over the parent, all other threads
+	 have been suspended already, leave this one suspended too.  */
+      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
+	  || event_lwp->bp_reinsert != 0)
 	new_lwp->suspended = 1;
 
       /* Normally we will get the pending SIGSTOP.  But in some cases
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 8/8] New test about step over clone syscall
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (5 preceding siblings ...)
  2016-02-19 14:37 ` [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Yao Qi
@ 2016-02-19 14:37 ` Yao Qi
  2016-02-23 20:31   ` Luis Machado
                     ` (2 more replies)
  2016-02-19 14:37 ` [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
  8 siblings, 3 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:37 UTC (permalink / raw)
  To: gdb-patches

This patch adds a new test for stepping over clone syscall.

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/step-over-syscall.exp (step_over_syscall): Kfail.
	Invoke step_over_syscall "clone".
	* gdb.base/step-over-clone.c: New file.
---
 gdb/testsuite/gdb.base/step-over-clone.c     | 53 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/step-over-syscall.exp | 17 +++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/step-over-clone.c

diff --git a/gdb/testsuite/gdb.base/step-over-clone.c b/gdb/testsuite/gdb.base/step-over-clone.c
new file mode 100644
index 0000000..43b1933
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-clone.c
@@ -0,0 +1,53 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <sched.h>
+
+static void
+marker () {}
+
+#define STACK_SIZE 0x1000
+
+static int
+clone_fn (void *unused)
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  int i, pid;
+  unsigned char *stack[6];
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    stack[i] = malloc (STACK_SIZE);
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    {
+      pid = clone (clone_fn, stack[i] + STACK_SIZE, CLONE_FILES | CLONE_VM,
+		   NULL);
+    }
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    free (stack[i]);
+
+  marker ();
+}
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index 863194b..e5a3d55 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -122,6 +122,13 @@ proc step_over_syscall { syscall } {
 	foreach displaced $disp_step_opts {
 	    with_test_prefix "displaced $displaced" {
 
+		if { $displaced == "on" && $syscall == "clone" } {
+		    # GDB doesn't support step over clone syscall with
+		    # displaced stepping.
+		    kfail "gdb/19675" "single step over clone"
+		    continue
+		}
+
 		gdb_test "continue" \
 		    "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
 		    "continue to $syscall (3rd time)"
@@ -187,6 +194,15 @@ proc step_over_syscall { syscall } {
 			}
 		    }
 
+		if { $syscall == "clone" } {
+		    # Create a breakpoint in the child with the condition
+		    # which is false, so that GDBserver can get the
+		    # event from the child but GDB doesn't see it.  In
+		    # this way, we don't have to adjust test flow for
+		    # "clone".
+		    gdb_test "break clone_fn if main == 0"
+		}
+
 		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
 		    "continue to $syscall again"
 
@@ -206,3 +222,4 @@ proc step_over_syscall { syscall } {
 
 step_over_syscall "fork"
 step_over_syscall "vfork"
+step_over_syscall "clone"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 6/8] Reformat disp-step-syscall.exp
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (3 preceding siblings ...)
  2016-02-19 14:36 ` [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c Yao Qi
@ 2016-02-19 14:37 ` Yao Qi
  2016-02-19 14:37 ` [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Yao Qi
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:37 UTC (permalink / raw)
  To: gdb-patches

Make the format of disp-step-syscall.exp correct.

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp: Format the code.
---
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 50 ++++++++++++++++------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 53ac1e1..128bb78 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -122,35 +122,41 @@ proc disp_step_cross_syscall { syscall } {
 	foreach displaced $disp_step_opts {
 	    with_test_prefix "displaced $displaced" {
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (3rd time)"
+		gdb_test "continue" \
+		    "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall (3rd time)"
 
-	# Hit the breakpoint on $syscall for the third time.  In this time, we'll set
-	# breakpoint on the syscall insn we recorded previously, and single step over it.
+		# Hit the breakpoint on $syscall for the third time.
+		# In this time, we'll set breakpoint on the syscall insn
+		# we recorded previously, and single step over it.
 
-	set syscall_insn_bp 0
-	gdb_test_multiple "break \*$syscall_insn_addr"  "break on syscall insn" {
-	    -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-		set syscall_insn_bp $expect_out(1,string)
-		pass "break on syscall insns"
-	    }
-	}
+		set syscall_insn_bp 0
+		gdb_test_multiple "break \*$syscall_insn_addr"  \
+		    "break on syscall insn" {
+			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+			    set syscall_insn_bp $expect_out(1,string)
+			    pass "break on syscall insns"
+			}
+		    }
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
-	    "continue to syscall insn $syscall"
+		gdb_test "continue" \
+		    "Continuing\\..*Breakpoint \[0-9\]+, .*" \
+		    "continue to syscall insn $syscall"
 
-	gdb_test_no_output "set displaced-stepping $displaced"
+		gdb_test_no_output "set displaced-stepping $displaced"
 
-	# Check the address of next instruction of syscall.
-	if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
-	    return -1
-	}
+		# Check the address of next instruction of syscall.
+		if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
+		    return -1
+		}
 
-	check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
+		check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
 
-	# Delete breakpoint syscall insns to avoid interference to other syscalls.
-	gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn"
-    }
+		# Delete breakpoint syscall insns to avoid interference
+		# to other syscalls.
+		gdb_test_no_output "delete $syscall_insn_bp" \
+		    "delete break $syscall insn"
+	    }
 	}
 
 	with_test_prefix "break cond on target" {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (6 preceding siblings ...)
  2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
@ 2016-02-19 14:37 ` Yao Qi
  2016-02-25 17:32   ` Pedro Alves
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
  8 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2016-02-19 14:37 UTC (permalink / raw)
  To: gdb-patches

disp-step-syscall.exp is extended for stepping over syscall instruction
in different cases, with or without displaced stepping, and stepping
over by GDBserver.

This patch rename disp-step-syscall.exp to step-over-syscall.exp to
reflect this.

gdb/testsuite:

2016-02-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-fork.c: Rename to ...
	* gdb.base/step-over-fork.c: ... it.  New file.
	* gdb.base/disp-step-vfork.c: Rename to ...
	* gdb.base/step-over-vfork.c: ... it.  New file.
	* gdb.base/disp-step-syscall.exp: Rename to ...
	* gdb.base/step-over-syscall.exp: ... it.  New file.
	(disp_step_cross_syscall): Rename to ...
	(step_over_syscall): ... it.
---
 gdb/testsuite/gdb.base/disp-step-fork.c      |  43 ------
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 208 ---------------------------
 gdb/testsuite/gdb.base/disp-step-vfork.c     |  47 ------
 gdb/testsuite/gdb.base/step-over-fork.c      |  43 ++++++
 gdb/testsuite/gdb.base/step-over-syscall.exp | 208 +++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/step-over-vfork.c     |  47 ++++++
 6 files changed, 298 insertions(+), 298 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-fork.c
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-syscall.exp
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-vfork.c
 create mode 100644 gdb/testsuite/gdb.base/step-over-fork.c
 create mode 100644 gdb/testsuite/gdb.base/step-over-syscall.exp
 create mode 100644 gdb/testsuite/gdb.base/step-over-vfork.c

diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c
deleted file mode 100644
index 6d477ea..0000000
--- a/gdb/testsuite/gdb.base/disp-step-fork.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2011-2016 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-static void
-marker () {}
-
-int
-main (void)
-{
-  int i, pid;
-
-  for (i = 0; i < 6; i++)
-    {
-      pid = fork ();
-      if (pid == 0) /* child */
-	{
-	  exit (0); /* at exit */
-	}
-      else
-	{
-	}
-    }
-
-  marker ();
-
-}
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
deleted file mode 100644
index 128bb78..0000000
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ /dev/null
@@ -1,208 +0,0 @@
-# This testcase is part of GDB, the GNU debugger.
-
-# Copyright 2011-2016 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-set syscall_insn ""
-
-# Define the syscall instruction for each target.
-
-if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
-    set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]"
-} elseif { [istarget "aarch64*-*-linux*"] || [istarget "arm*-*-linux*"] } {
-    set syscall_insn "\[ \t\](swi|svc)\[ \t\]"
-} else {
-    return -1
-}
-
-proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
-    set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
-
-    set test "single step over $syscall final pc"
-    if {$syscall_insn_next_addr != 0
-	&& $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
-	pass $test
-    } else {
-	fail $test
-    }
-}
-
-proc disp_step_cross_syscall { syscall } {
-    with_test_prefix "$syscall" {
-	global syscall_insn
-	global gdb_prompt
-
-	set testfile "disp-step-$syscall"
-
-	if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
-	    untested ${testfile}.exp
-	    return -1
-	}
-
-	if { ![runto main] } then {
-	    fail "run to main ($syscall)"
-	    return
-	}
-
-	# Delete the breakpoint on main.
-	gdb_test_no_output "delete break 1"
-
-	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
-	gdb_test_no_output "set displaced-stepping off"
-
-	set syscall_bp 0
-	gdb_test_multiple "break $syscall"  "break $syscall" {
-	    -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-		set syscall_bp $expect_out(1,string)
-		pass "break $syscall"
-	    }
-	}
-
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (1st time)"
-	# Hit the breakpoint on $syscall for the first time.  In this time, we will let PLT
-	# resolution done, and the number single steps we will do later will be
-	# reduced.
-
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (2nd time)"
-	# Hit the breakpoint on $syscall for the second time.  In this time, the address
-	# of syscall insn and next insn of syscall are recorded.
-
-	gdb_test "display/i \$pc" ".*"
-
-
-	# Single step until we see a syscall insn or we reach the
-	# upper bound of loop iterations.
-	set msg "find syscall insn in $syscall"
-	set steps 0
-	set max_steps 1000
-	gdb_test_multiple "stepi" $msg {
-	    -re ".*$syscall_insn.*$gdb_prompt $" {
-		pass $msg
-	    }
-	    -re "x/i .*=>.*\r\n$gdb_prompt $" {
-		incr steps
-		if {$steps == $max_steps} {
-		    fail $msg
-		} else {
-		    send_gdb "stepi\n"
-		    exp_continue
-		}
-	    }
-	}
-
-	if {$steps == $max_steps} {
-	    return -1
-	}
-
-	set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
-	if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
-	    return -1
-	}
-	set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"]
-
-	set disp_step_opts { "off" }
-	if { [support_displaced_stepping] } {
-	    lappend disp_step_opts "on"
-	}
-
-	foreach displaced $disp_step_opts {
-	    with_test_prefix "displaced $displaced" {
-
-		gdb_test "continue" \
-		    "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-		    "continue to $syscall (3rd time)"
-
-		# Hit the breakpoint on $syscall for the third time.
-		# In this time, we'll set breakpoint on the syscall insn
-		# we recorded previously, and single step over it.
-
-		set syscall_insn_bp 0
-		gdb_test_multiple "break \*$syscall_insn_addr"  \
-		    "break on syscall insn" {
-			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-			    set syscall_insn_bp $expect_out(1,string)
-			    pass "break on syscall insns"
-			}
-		    }
-
-		gdb_test "continue" \
-		    "Continuing\\..*Breakpoint \[0-9\]+, .*" \
-		    "continue to syscall insn $syscall"
-
-		gdb_test_no_output "set displaced-stepping $displaced"
-
-		# Check the address of next instruction of syscall.
-		if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
-		    return -1
-		}
-
-		check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
-
-		# Delete breakpoint syscall insns to avoid interference
-		# to other syscalls.
-		gdb_test_no_output "delete $syscall_insn_bp" \
-		    "delete break $syscall insn"
-	    }
-	}
-
-	with_test_prefix "break cond on target" {
-	    set cond_bp_target 1
-
-	    set test "set breakpoint condition-evaluation target"
-	    gdb_test_multiple $test $test {
-		-re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
-		    # Target doesn't support breakpoint condition
-		    # evaluation on its side.
-		    set cond_bp_target 0
-		}
-		-re "^$test\r\n$gdb_prompt $" {
-		}
-	    }
-
-	    if { $cond_bp_target } {
-		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-		    "continue to $syscall"
-
-		# Create a breakpoint with the condition which is false.
-		set syscall_insn_bp 0
-		gdb_test_multiple "break \*$syscall_insn_addr if main == 0" \
-		    "break on syscall insns" {
-			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-			    set syscall_insn_bp $expect_out(1,string)
-			    pass "break on syscall insns"
-			}
-		    }
-
-		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-		    "continue to $syscall again"
-
-		# Delete breakpoint syscall insns to avoid interference to
-		# other syscalls.
-		gdb_test_no_output "delete $syscall_insn_bp" \
-		    "delete break $syscall insn"
-	    }
-	}
-
-	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
-
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
-	    "continue to marker ($syscall)"
-    }
-}
-
-disp_step_cross_syscall "fork"
-disp_step_cross_syscall "vfork"
diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/disp-step-vfork.c
deleted file mode 100644
index 35665ab..0000000
--- a/gdb/testsuite/gdb.base/disp-step-vfork.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2011-2016 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <unistd.h>
-
-static void
-marker () {}
-
-int
-main (void)
-{
-  int i, pid;
-
-  for (i = 0; i < 6; i++)
-    {
-      pid = vfork ();
-      if (pid == -1)
-	{
-	  return 1;
-	}
-      else if (pid != 0)
-	{
-	}
-      else
-	{
-	  _exit (0);
-	}
-    }
-
-  marker ();
-  return 0;
-
-}
diff --git a/gdb/testsuite/gdb.base/step-over-fork.c b/gdb/testsuite/gdb.base/step-over-fork.c
new file mode 100644
index 0000000..6d477ea
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-fork.c
@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011-2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+static void
+marker () {}
+
+int
+main (void)
+{
+  int i, pid;
+
+  for (i = 0; i < 6; i++)
+    {
+      pid = fork ();
+      if (pid == 0) /* child */
+	{
+	  exit (0); /* at exit */
+	}
+      else
+	{
+	}
+    }
+
+  marker ();
+
+}
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
new file mode 100644
index 0000000..863194b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -0,0 +1,208 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2011-2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set syscall_insn ""
+
+# Define the syscall instruction for each target.
+
+if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
+    set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]"
+} elseif { [istarget "aarch64*-*-linux*"] || [istarget "arm*-*-linux*"] } {
+    set syscall_insn "\[ \t\](swi|svc)\[ \t\]"
+} else {
+    return -1
+}
+
+proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
+    set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
+
+    set test "single step over $syscall final pc"
+    if {$syscall_insn_next_addr != 0
+	&& $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
+	pass $test
+    } else {
+	fail $test
+    }
+}
+
+proc step_over_syscall { syscall } {
+    with_test_prefix "$syscall" {
+	global syscall_insn
+	global gdb_prompt
+
+	set testfile "step-over-$syscall"
+
+	if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
+	    untested ${testfile}.exp
+	    return -1
+	}
+
+	if { ![runto main] } then {
+	    fail "run to main ($syscall)"
+	    return
+	}
+
+	# Delete the breakpoint on main.
+	gdb_test_no_output "delete break 1"
+
+	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
+	gdb_test_no_output "set displaced-stepping off"
+
+	set syscall_bp 0
+	gdb_test_multiple "break $syscall"  "break $syscall" {
+	    -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+		set syscall_bp $expect_out(1,string)
+		pass "break $syscall"
+	    }
+	}
+
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	    "continue to $syscall (1st time)"
+	# Hit the breakpoint on $syscall for the first time.  In this time, we will let PLT
+	# resolution done, and the number single steps we will do later will be
+	# reduced.
+
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	    "continue to $syscall (2nd time)"
+	# Hit the breakpoint on $syscall for the second time.  In this time, the address
+	# of syscall insn and next insn of syscall are recorded.
+
+	gdb_test "display/i \$pc" ".*"
+
+
+	# Single step until we see a syscall insn or we reach the
+	# upper bound of loop iterations.
+	set msg "find syscall insn in $syscall"
+	set steps 0
+	set max_steps 1000
+	gdb_test_multiple "stepi" $msg {
+	    -re ".*$syscall_insn.*$gdb_prompt $" {
+		pass $msg
+	    }
+	    -re "x/i .*=>.*\r\n$gdb_prompt $" {
+		incr steps
+		if {$steps == $max_steps} {
+		    fail $msg
+		} else {
+		    send_gdb "stepi\n"
+		    exp_continue
+		}
+	    }
+	}
+
+	if {$steps == $max_steps} {
+	    return -1
+	}
+
+	set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
+	if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
+	    return -1
+	}
+	set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"]
+
+	set disp_step_opts { "off" }
+	if { [support_displaced_stepping] } {
+	    lappend disp_step_opts "on"
+	}
+
+	foreach displaced $disp_step_opts {
+	    with_test_prefix "displaced $displaced" {
+
+		gdb_test "continue" \
+		    "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall (3rd time)"
+
+		# Hit the breakpoint on $syscall for the third time.
+		# In this time, we'll set breakpoint on the syscall insn
+		# we recorded previously, and single step over it.
+
+		set syscall_insn_bp 0
+		gdb_test_multiple "break \*$syscall_insn_addr"  \
+		    "break on syscall insn" {
+			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+			    set syscall_insn_bp $expect_out(1,string)
+			    pass "break on syscall insns"
+			}
+		    }
+
+		gdb_test "continue" \
+		    "Continuing\\..*Breakpoint \[0-9\]+, .*" \
+		    "continue to syscall insn $syscall"
+
+		gdb_test_no_output "set displaced-stepping $displaced"
+
+		# Check the address of next instruction of syscall.
+		if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
+		    return -1
+		}
+
+		check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
+
+		# Delete breakpoint syscall insns to avoid interference
+		# to other syscalls.
+		gdb_test_no_output "delete $syscall_insn_bp" \
+		    "delete break $syscall insn"
+	    }
+	}
+
+	with_test_prefix "break cond on target" {
+	    set cond_bp_target 1
+
+	    set test "set breakpoint condition-evaluation target"
+	    gdb_test_multiple $test $test {
+		-re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
+		    # Target doesn't support breakpoint condition
+		    # evaluation on its side.
+		    set cond_bp_target 0
+		}
+		-re "^$test\r\n$gdb_prompt $" {
+		}
+	    }
+
+	    if { $cond_bp_target } {
+		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall"
+
+		# Create a breakpoint with the condition which is false.
+		set syscall_insn_bp 0
+		gdb_test_multiple "break \*$syscall_insn_addr if main == 0" \
+		    "break on syscall insns" {
+			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+			    set syscall_insn_bp $expect_out(1,string)
+			    pass "break on syscall insns"
+			}
+		    }
+
+		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		    "continue to $syscall again"
+
+		# Delete breakpoint syscall insns to avoid interference to
+		# other syscalls.
+		gdb_test_no_output "delete $syscall_insn_bp" \
+		    "delete break $syscall insn"
+	    }
+	}
+
+	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
+
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
+	    "continue to marker ($syscall)"
+    }
+}
+
+step_over_syscall "fork"
+step_over_syscall "vfork"
diff --git a/gdb/testsuite/gdb.base/step-over-vfork.c b/gdb/testsuite/gdb.base/step-over-vfork.c
new file mode 100644
index 0000000..35665ab
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-vfork.c
@@ -0,0 +1,47 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011-2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+
+static void
+marker () {}
+
+int
+main (void)
+{
+  int i, pid;
+
+  for (i = 0; i < 6; i++)
+    {
+      pid = vfork ();
+      if (pid == -1)
+	{
+	  return 1;
+	}
+      else if (pid != 0)
+	{
+	}
+      else
+	{
+	  _exit (0);
+	}
+    }
+
+  marker ();
+  return 0;
+
+}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/8] [GDBserver] Leave child suspended when step over parent
  2016-02-19 14:37 ` [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Yao Qi
@ 2016-02-23 20:23   ` Luis Machado
  2016-02-25 17:12   ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Luis Machado @ 2016-02-23 20:23 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/19/2016 12:36 PM, Yao Qi wrote:
> I see the following GDBserver internal error in two cases,
>
>   gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
>   unsuspend LWP 17200, suspended=-1
>
>   1. step over a breakpoint on fork/vfork syscall instruction,
>   2. step over a breakpoint on clone syscall instruction and child
>      threads hits a breakpoint,
>
> the stack backtrace is
>
>   #0  internal_error (file=file@entry=0x44c4c0 "gdb/gdbserver/linux-low.c", line=line@entry=1922,
>      fmt=fmt@entry=0x44c7d0 "unsuspend LWP %ld, suspended=%d\n") at gdb/gdbserver/../common/errors.c:51
>   #1  0x0000000000424014 in lwp_suspended_decr (lwp=<optimised out>, lwp=<optimised out>) at gdb/gdbserver/linux-low.c:1922
>   #2  0x000000000042403a in unsuspend_one_lwp (entry=<optimised out>, except=0x66e8c0) at gdb/gdbserver/linux-low.c:2885
>   #3  0x0000000000405f45 in find_inferior (list=<optimised out>, func=func@entry=0x424020 <unsuspend_one_lwp>, arg=arg@entry=0x66e8c0)
>      at gdb/gdbserver/inferiors.c:243
>   #4  0x00000000004297de in unsuspend_all_lwps (except=0x66e8c0) at gdb/gdbserver/linux-low.c:2895
>   #5  linux_wait_1 (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, target_options=target_options@entry=0)
>      at gdb/gdbserver/linux-low.c:3632
>   #6  0x000000000042a764 in linux_wait (ptid=..., ourstatus=0x665ec0 <last_status>, target_options=0)
>      at gdb/gdbserver/linux-low.c:3770
>   #7  0x0000000000411163 in mywait (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, options=options@entry=0, connected_wait=connected_wait@entry=1)
>      at gdb/gdbserver/target.c:214
>   #8  0x000000000040b1f2 in resume (actions=0x66f800, num_actions=1) at gdb/gdbserver/server.c:2757
>   #9  0x000000000040f660 in handle_v_cont (own_buf=0x66a630 "vCont;c:p45e9.-1") at gdb/gdbserver/server.c:2719
>
> when GDBserver steps over a thread, other threads have been suspended,
> the "stepping" thread may create new thread, but GDBserver doesn't set
> it suspend count to 1.  When GDBserver unsuspend threads, the child's
> suspend count goes to -1, and the assert is triggered.  In fact, GDBserver
> has already taken care of suspend count of new thread when GDBserver is
> suspending all threads except the one GDBserver wants to step over by
> https://sourceware.org/ml/gdb-patches/2015-07/msg00946.html
>
> +	  /* If we're suspending all threads, leave this one suspended
> +	     too.  */
> +	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
> +	    {
> +	      if (debug_threads)
> +		debug_printf ("HEW: leaving child suspended\n");
> +	      child_lwp->suspended = 1;
> +	    }
>
> but that is not enough, because new thread can be still spawned in
> the thread which is being stepped over.  This patch extends the
> condition that GDBserver set child's suspend count to one if it is
> suspending threads or stepping over the thread.
>
> gdb/gdbserver:
>
> 2016-02-19  Yao Qi  <yao.qi@linaro.org>
>
> 	* linux-low.c (handle_extended_wait): Set child suspended
> 	if event_lwp->bp_reinsert isn't zero.
> ---
>   gdb/gdbserver/linux-low.c | 14 +++++++++-----
>   1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
> index 3f085fd..3765e08 100644
> --- a/gdb/gdbserver/linux-low.c
> +++ b/gdb/gdbserver/linux-low.c
> @@ -529,8 +529,10 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
>   	  child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
>
>   	  /* If we're suspending all threads, leave this one suspended
> -	     too.  */
> -	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
> +	     too.  If we're stepping over the parent, all other threads
> +	     have been suspended already, leave this one suspended too.  */
> +	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
> +	      || event_lwp->bp_reinsert != 0)
>   	    {
>   	      if (debug_threads)
>   		debug_printf ("HEW: leaving child suspended\n");
> @@ -583,9 +585,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
>   	 before calling linux_resume_one_lwp.  */
>         new_lwp->stopped = 1;
>
> -     /* If we're suspending all threads, leave this one suspended
> -	too.  */
> -      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
> +      /* If we're suspending all threads, leave this one suspended
> +	 too.  If we're stepping over the parent, all other threads
> +	 have been suspended already, leave this one suspended too.  */
> +      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
> +	  || event_lwp->bp_reinsert != 0)
>   	new_lwp->suspended = 1;
>
>         /* Normally we will get the pending SIGSTOP.  But in some cases
>

The comment is a bit off with regards to what is really being checked 
here. Maybe it is the code, but "event_lwp->bp_reinsert != 0" doesn't 
exactly translate to "stepping over the parent".

Maybe things would improve if we defined what "this one" means in the 
second case. It is a new thread or a child process thread, right?

I'm looking at the two hunks above and they seem to want to be unified, 
but it is beside the point of the patch. :-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver
  2016-02-19 14:36 ` [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver Yao Qi
@ 2016-02-23 20:28   ` Luis Machado
  2016-02-25 17:31   ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Luis Machado @ 2016-02-23 20:28 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

Just one comment nit.

On 02/19/2016 12:36 PM, Yao Qi wrote:
> We can also extend disp-step-syscall.exp to test GDBserver step over
> breakpoint on syscall instruction.  That is, we set a breakpoint
> with a false condition on syscall instruction, so that GDBserver will
> step over it.
>
> This test triggers a GDBserver internal error, which can be fixed by
> this series.
>
> (gdb) PASS: gdb.base/disp-step-syscall.exp: fork: break cond on target: break on syscall insns
> continue^M
> Continuing.^M
> Remote connection closed^M
> (gdb) FAIL: gdb.base/disp-step-syscall.exp: fork: break cond on target: continue to fork again
>
> In GDBserver, there is an internal error,
>
> /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
> unsuspend LWP 25554, suspended=-1
>
> the simplified reproducer is like,
>
> $ ./gdb ./testsuite/outputs/gdb.base/disp-step-syscall/disp-step-fork
> (gdb) b main
> (gdb) c
> (gdb) disassemble fork // in order to find the address of insn 'syscall'
> ....
>     0x00007ffff7ad6023 <+179>:	syscall
> (gdb) b *0x00007ffff7ad6023 if main == 0
> (gdb) c
>
> gdb/testsuite:
>
> 2016-02-19  Yao Qi  <yao.qi@linaro.org>
>
> 	* gdb.base/disp-step-fork.c (main): Increase loop boundary.
> 	* gdb.base/disp-step-vfork.c (main): Likewise.
> 	* gdb.base/disp-step-syscall.exp (disp_step_cross_syscall): Test
> 	breakpoint condition evaluated on the target side.
> ---
>   gdb/testsuite/gdb.base/disp-step-fork.c      |  2 +-
>   gdb/testsuite/gdb.base/disp-step-syscall.exp | 38 ++++++++++++++++++++++++++++
>   gdb/testsuite/gdb.base/disp-step-vfork.c     |  2 +-
>   3 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/disp-step-fork.c
> index d8d602f..6d477ea 100644
> --- a/gdb/testsuite/gdb.base/disp-step-fork.c
> +++ b/gdb/testsuite/gdb.base/disp-step-fork.c
> @@ -26,7 +26,7 @@ main (void)
>   {
>     int i, pid;
>
> -  for (i = 0; i < 4; i++)
> +  for (i = 0; i < 6; i++)
>       {
>         pid = fork ();
>         if (pid == 0) /* child */
> diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
> index 9e43fbb..53ac1e1 100644
> --- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
> +++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
> @@ -153,6 +153,44 @@ proc disp_step_cross_syscall { syscall } {
>       }
>   	}
>
> +	with_test_prefix "break cond on target" {
> +	    set cond_bp_target 1
> +
> +	    set test "set breakpoint condition-evaluation target"
> +	    gdb_test_multiple $test $test {
> +		-re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
> +		    # Target doesn't support breakpoint condition
> +		    # evaluation on its side.
> +		    set cond_bp_target 0
> +		}
> +		-re "^$test\r\n$gdb_prompt $" {
> +		}
> +	    }
> +
> +	    if { $cond_bp_target } {
> +		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
> +		    "continue to $syscall"
> +
> +		# Create a breakpoint with the condition which is false.
> +		set syscall_insn_bp 0
> +		gdb_test_multiple "break \*$syscall_insn_addr if main == 0" \
> +		    "break on syscall insns" {
> +			-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
> +			    set syscall_insn_bp $expect_out(1,string)
> +			    pass "break on syscall insns"
> +			}
> +		    }
> +
> +		gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
> +		    "continue to $syscall again"
> +
> +		# Delete breakpoint syscall insns to avoid interference to

"... interference with..."?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 8/8] New test about step over clone syscall
  2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
@ 2016-02-23 20:31   ` Luis Machado
  2016-02-25 17:43   ` Pedro Alves
  2016-02-25 17:43   ` Pedro Alves
  2 siblings, 0 replies; 30+ messages in thread
From: Luis Machado @ 2016-02-23 20:31 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/19/2016 12:36 PM, Yao Qi wrote:
> This patch adds a new test for stepping over clone syscall.
>
> 2016-02-19  Yao Qi  <yao.qi@linaro.org>
>
> 	* gdb.base/step-over-syscall.exp (step_over_syscall): Kfail.
> 	Invoke step_over_syscall "clone".
> 	* gdb.base/step-over-clone.c: New file.
> ---
>   gdb/testsuite/gdb.base/step-over-clone.c     | 53 ++++++++++++++++++++++++++++
>   gdb/testsuite/gdb.base/step-over-syscall.exp | 17 +++++++++
>   2 files changed, 70 insertions(+)
>   create mode 100644 gdb/testsuite/gdb.base/step-over-clone.c
>
> diff --git a/gdb/testsuite/gdb.base/step-over-clone.c b/gdb/testsuite/gdb.base/step-over-clone.c
> new file mode 100644
> index 0000000..43b1933
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/step-over-clone.c
> @@ -0,0 +1,53 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2016 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#define _GNU_SOURCE
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <sched.h>
> +
> +static void
> +marker () {}
> +
> +#define STACK_SIZE 0x1000
> +
> +static int
> +clone_fn (void *unused)
> +{
> +  return 0;
> +}
> +
> +int
> +main (void)
> +{
> +  int i, pid;
> +  unsigned char *stack[6];
> +
> +  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
> +    stack[i] = malloc (STACK_SIZE);
> +
> +  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
> +    {
> +      pid = clone (clone_fn, stack[i] + STACK_SIZE, CLONE_FILES | CLONE_VM,
> +		   NULL);
> +    }
> +
> +  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
> +    free (stack[i]);
> +
> +  marker ();
> +}
> diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
> index 863194b..e5a3d55 100644
> --- a/gdb/testsuite/gdb.base/step-over-syscall.exp
> +++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
> @@ -122,6 +122,13 @@ proc step_over_syscall { syscall } {
>   	foreach displaced $disp_step_opts {
>   	    with_test_prefix "displaced $displaced" {
>
> +		if { $displaced == "on" && $syscall == "clone" } {
> +		    # GDB doesn't support step over clone syscall with

"...stepping over clone ..."?

> +		    # displaced stepping.
> +		    kfail "gdb/19675" "single step over clone"
> +		    continue
> +		}
> +
>   		gdb_test "continue" \
>   		    "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
>   		    "continue to $syscall (3rd time)"
> @@ -187,6 +194,15 @@ proc step_over_syscall { syscall } {
>   			}
>   		    }
>
> +		if { $syscall == "clone" } {
> +		    # Create a breakpoint in the child with the condition
> +		    # which is false, so that GDBserver can get the
> +		    # event from the child but GDB doesn't see it.  In
> +		    # this way, we don't have to adjust test flow for

"... to adjust the test flow..."?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/8] [GDBserver] Leave child suspended when step over parent
  2016-02-19 14:37 ` [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Yao Qi
  2016-02-23 20:23   ` Luis Machado
@ 2016-02-25 17:12   ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:12 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

LGTM.

On 02/19/2016 02:36 PM, Yao Qi wrote:

>  	  /* If we're suspending all threads, leave this one suspended
> -	     too.  */
> -	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
> +	     too.  If we're stepping over the parent, all other threads
> +	     have been suspended already, leave this one suspended too.  */

I'd write:

	     too.  If the fork/clone parent is stepping over a breakpoint, all
             other threads have been suspended already.  Leave the child
             suspended too.  */

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/8] Step over syscalll insn with disp-step on and off
  2016-02-19 14:36 ` [PATCH 4/8] Step over syscalll insn with disp-step on and off Yao Qi
@ 2016-02-25 17:27   ` Pedro Alves
  0 siblings, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:27 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

LGTM, though minor comments below.

On 02/19/2016 02:36 PM, Yao Qi wrote:
> +	set disp_step_opts { "off" }
> +	if { [support_displaced_stepping] } {
> +	    lappend disp_step_opts "on"
> +	}
> +
> +	foreach displaced $disp_step_opts {
> +	    with_test_prefix "displaced $displaced" {
> +

This can be a single:

	foreach_with_prefix displaced $disp_step_opts {



BTW, I usually write these as:

	foreach_with_prefix displaced {"off" "on"} {
          if {$displaced == "on" && ![support_displaced_stepping]} {
	     continue
	  }

          ... tests or proc call here  ..
        }

It makes it easier to scan the testing axis covered, particularly
when you have multiple nested foreach loops, IMO.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c
  2016-02-19 14:36 ` [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c Yao Qi
@ 2016-02-25 17:28   ` Pedro Alves
  0 siblings, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:28 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/19/2016 02:36 PM, Yao Qi wrote:
> We can call fork/vfork more easily in the test.

How about instead simply restarting the program / gdb?  Keeping the program
alive for multiple test sequences is more prone to cascading FAILs.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver
  2016-02-19 14:36 ` [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver Yao Qi
  2016-02-23 20:28   ` Luis Machado
@ 2016-02-25 17:31   ` Pedro Alves
  1 sibling, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:31 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

LGTM.

On 02/19/2016 02:36 PM, Yao Qi wrote:

> +		# Create a breakpoint with the condition which is false.

Suggest:

   # Create a breakpoint with a condition that evals false.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp
  2016-02-19 14:37 ` [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
@ 2016-02-25 17:32   ` Pedro Alves
  0 siblings, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:32 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

We should really start requiring git diff -M.  :-)

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 8/8] New test about step over clone syscall
  2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
  2016-02-23 20:31   ` Luis Machado
@ 2016-02-25 17:43   ` Pedro Alves
  2016-02-25 17:43   ` Pedro Alves
  2 siblings, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:43 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/19/2016 02:36 PM, Yao Qi wrote:
> +		if { $syscall == "clone" } {
> +		    # Create a breakpoint in the child with the condition
> +		    # which is false, so that GDBserver can get the
> +		    # event from the child but GDB doesn't see it.  In
> +		    # this way, we don't have to adjust test flow for
> +		    # "clone".

I think this comment should mention this is a regression test for
a previous bug.  I'd file the description of patch #1 as a PR,
and reference the PR here.  I had read that patch before this one,
and it took me a bit to see the connection.

> +		    gdb_test "break clone_fn if main == 0"
> +		}

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 8/8] New test about step over clone syscall
  2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
  2016-02-23 20:31   ` Luis Machado
  2016-02-25 17:43   ` Pedro Alves
@ 2016-02-25 17:43   ` Pedro Alves
  2 siblings, 0 replies; 30+ messages in thread
From: Pedro Alves @ 2016-02-25 17:43 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/19/2016 02:36 PM, Yao Qi wrote:
> +static void
> +marker () {}

static void
marker (void)
{
}

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/7 V2] Leave child suspended when step over parent
  2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
                   ` (7 preceding siblings ...)
  2016-02-19 14:37 ` [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
@ 2016-02-26 14:03 ` Yao Qi
  2016-02-26 14:04   ` [PATCH 7/7] New test about step over clone syscall Yao Qi
                     ` (7 more replies)
  8 siblings, 8 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:03 UTC (permalink / raw)
  To: gdb-patches

Hi,
Here is the v2 of this patch series.  V1 can be found
https://sourceware.org/ml/gdb-patches/2016-02/msg00591.html

The changes in v2 are:

 1. Remove patch "Use loop in disp-step-fork.c and disp-step-vfork.c"
    from this series,
 2. Open PR server/19736 for the bug this series fixes, and mention
    this PR in the comments of tests,
 3. Restart GDB in each test instead of doing multiple tests in a
    single debugging session,
 4. Fix some wording issues in the comments.
 5. Use foreach_with_prefix,

*** BLURB HERE ***

Yao Qi (7):
  [GDBserver] Leave child suspended when step over parent
  Refactor gdb.base/disp-step-syscall.exp for general step over test
  Step over syscalll insn with disp-step on and off
  Step over fork/vfork syscall insn in gdbserver
  Rename disp-step-syscall.exp to step-over-syscall.exp
  Reformat gdb.base/step-over-syscall.exp
  New test about step over clone syscall

 gdb/gdbserver/linux-low.c                          |  16 +-
 gdb/testsuite/gdb.base/disp-step-syscall.exp       | 154 -------------
 gdb/testsuite/gdb.base/step-over-clone.c           |  54 +++++
 .../{disp-step-fork.c => step-over-fork.c}         |   0
 gdb/testsuite/gdb.base/step-over-syscall.exp       | 249 +++++++++++++++++++++
 .../{disp-step-vfork.c => step-over-vfork.c}       |   0
 6 files changed, 314 insertions(+), 159 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.base/disp-step-syscall.exp
 create mode 100644 gdb/testsuite/gdb.base/step-over-clone.c
 rename gdb/testsuite/gdb.base/{disp-step-fork.c => step-over-fork.c} (100%)
 create mode 100644 gdb/testsuite/gdb.base/step-over-syscall.exp
 rename gdb/testsuite/gdb.base/{disp-step-vfork.c => step-over-vfork.c} (100%)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 5/7] Rename disp-step-syscall.exp to step-over-syscall.exp
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
  2016-02-26 14:04   ` [PATCH 7/7] New test about step over clone syscall Yao Qi
  2016-02-26 14:04   ` [PATCH 2/7] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 14:04   ` [PATCH 3/7] Step over syscalll insn with disp-step on and off Yao Qi
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

disp-step-syscall.exp is extended for stepping over syscall instruction
in different cases, with or without displaced stepping, and stepping
over by GDBserver.

This patch rename disp-step-syscall.exp to step-over-syscall.exp to
reflect this.

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-fork.c: Rename to ...
	* gdb.base/step-over-fork.c: ... it.  New file.
	* gdb.base/disp-step-vfork.c: Rename to ...
	* gdb.base/step-over-vfork.c: ... it.  New file.
	* gdb.base/disp-step-syscall.exp: Rename to ...
	* gdb.base/step-over-syscall.exp: ... it.  New file.
	(disp_step_cross_syscall): Rename to ...
	(step_over_syscall): ... it.
---
 .../gdb.base/{disp-step-fork.c => step-over-fork.c}        |  0
 .../{disp-step-syscall.exp => step-over-syscall.exp}       | 14 +++++++-------
 .../gdb.base/{disp-step-vfork.c => step-over-vfork.c}      |  0
 3 files changed, 7 insertions(+), 7 deletions(-)
 rename gdb/testsuite/gdb.base/{disp-step-fork.c => step-over-fork.c} (100%)
 rename gdb/testsuite/gdb.base/{disp-step-syscall.exp => step-over-syscall.exp} (96%)
 rename gdb/testsuite/gdb.base/{disp-step-vfork.c => step-over-vfork.c} (100%)

diff --git a/gdb/testsuite/gdb.base/disp-step-fork.c b/gdb/testsuite/gdb.base/step-over-fork.c
similarity index 100%
rename from gdb/testsuite/gdb.base/disp-step-fork.c
rename to gdb/testsuite/gdb.base/step-over-fork.c
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
similarity index 96%
rename from gdb/testsuite/gdb.base/disp-step-syscall.exp
rename to gdb/testsuite/gdb.base/step-over-syscall.exp
index 9ecf2a5..6146f64 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -47,7 +47,7 @@ proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
 proc setup { syscall } {
     global gdb_prompt syscall_insn
 
-    set testfile "disp-step-$syscall"
+    set testfile "step-over-$syscall"
 
     clean_restart $testfile
 
@@ -107,12 +107,12 @@ proc setup { syscall } {
     return [list $syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]]
 }
 
-proc disp_step_cross_syscall { syscall } {
+proc step_over_syscall { syscall } {
     with_test_prefix "$syscall" {
 	global syscall_insn
 	global gdb_prompt
 
-	set testfile "disp-step-$syscall"
+	set testfile "step-over-$syscall"
 
 	if [build_executable ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
 	    untested ${testfile}.exp
@@ -174,7 +174,7 @@ proc disp_step_cross_syscall { syscall } {
 
 proc break_cond_on_syscall { syscall } {
     with_test_prefix "break cond on target : $syscall" {
-	set testfile "disp-step-$syscall"
+	set testfile "step-over-$syscall"
 
 	set ret [setup $syscall]
 
@@ -200,10 +200,10 @@ proc break_cond_on_syscall { syscall } {
     }
 }
 
-disp_step_cross_syscall "fork"
-disp_step_cross_syscall "vfork"
+step_over_syscall "fork"
+step_over_syscall "vfork"
 
-set testfile "disp-step-fork"
+set testfile "step-over-fork"
 clean_restart $testfile
 if { ![runto main] } then {
     fail "run to main"
diff --git a/gdb/testsuite/gdb.base/disp-step-vfork.c b/gdb/testsuite/gdb.base/step-over-vfork.c
similarity index 100%
rename from gdb/testsuite/gdb.base/disp-step-vfork.c
rename to gdb/testsuite/gdb.base/step-over-vfork.c
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 6/7] Reformat gdb.base/step-over-syscall.exp
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
                     ` (4 preceding siblings ...)
  2016-02-26 14:04   ` [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 14:04   ` [PATCH 1/7] [GDBserver] Leave child suspended when step over parent Yao Qi
  2016-03-03  9:21   ` [PATCH 0/7 V2] " Yao Qi
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/step-over-syscall.exp (disp_step_cross_syscall): Fix
	code format.
---
 gdb/testsuite/gdb.base/step-over-syscall.exp | 59 ++++++++++++++--------------
 1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index 6146f64..5d2b296 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -124,46 +124,45 @@ proc step_over_syscall { syscall } {
 		continue
 	    }
 
-	set ret [setup $syscall]
+	    set ret [setup $syscall]
 
-	set syscall_insn_addr [lindex $ret 0]
-	set syscall_insn_next_addr [lindex $ret 1]
-	if { $syscall_insn_addr == -1 } {
-	    return -1
-	}
+	    set syscall_insn_addr [lindex $ret 0]
+	    set syscall_insn_next_addr [lindex $ret 1]
+	    if { $syscall_insn_addr == -1 } {
+		return -1
+	    }
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (3rd time)"
+	    gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+		"continue to $syscall (3rd time)"
 
-	# Hit the breakpoint on $syscall for the third time.  In this time, we'll set
-	# breakpoint on the syscall insn we recorded previously, and single step over it.
+	    # Hit the breakpoint on $syscall for the third time.  In this time, we'll set
+	    # breakpoint on the syscall insn we recorded previously, and single step over it.
 
-	set syscall_insn_bp 0
-	gdb_test_multiple "break \*$syscall_insn_addr"  "break on syscall insn" {
-	    -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-		set syscall_insn_bp $expect_out(1,string)
-		pass "break on syscall insns"
+	    set syscall_insn_bp 0
+	    gdb_test_multiple "break \*$syscall_insn_addr"  "break on syscall insn" {
+		-re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
+		    set syscall_insn_bp $expect_out(1,string)
+		    pass "break on syscall insns"
+		}
 	    }
-	}
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
-	    "continue to syscall insn $syscall"
+	    gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
+		"continue to syscall insn $syscall"
 
-	gdb_test_no_output "set displaced-stepping $displaced"
+	    gdb_test_no_output "set displaced-stepping $displaced"
 
-	# Check the address of next instruction of syscall.
-	if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
-	    return -1
-	}
+	    # Check the address of next instruction of syscall.
+	    if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
+		return -1
+	    }
+	    check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
 
-	check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
+	    # Delete breakpoint syscall insns to avoid interference to other syscalls.
+	    delete_breakpoints
 
-	# Delete breakpoint syscall insns to avoid interference to other syscalls.
-	delete_breakpoints
-
-	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
-	    "continue to marker ($syscall)"
+	    gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
+	    gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
+		"continue to marker ($syscall)"
 	}
     }
 }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 7/7] New test about step over clone syscall
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 14:04   ` [PATCH 2/7] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

This patch adds a new test for stepping over clone syscall.

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/step-over-syscall.exp (step_over_syscall): Kfail.
	Invoke step_over_syscall "clone" and break_cond_on_syscall
	"clone".
	* gdb.base/step-over-clone.c: New file.
---
 gdb/testsuite/gdb.base/step-over-clone.c     | 54 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/step-over-syscall.exp | 21 +++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/step-over-clone.c

diff --git a/gdb/testsuite/gdb.base/step-over-clone.c b/gdb/testsuite/gdb.base/step-over-clone.c
new file mode 100644
index 0000000..57ecbbf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-clone.c
@@ -0,0 +1,54 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <sched.h>
+
+static void
+marker ()
+{}
+
+#define STACK_SIZE 0x1000
+
+static int
+clone_fn (void *unused)
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  int i, pid;
+  unsigned char *stack[6];
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    stack[i] = malloc (STACK_SIZE);
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    {
+      pid = clone (clone_fn, stack[i] + STACK_SIZE, CLONE_FILES | CLONE_VM,
+		   NULL);
+    }
+
+  for (i = 0; i < (sizeof (stack) / sizeof (stack[0])); i++)
+    free (stack[i]);
+
+  marker ();
+}
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index 5d2b296..3c1beb7 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -124,6 +124,13 @@ proc step_over_syscall { syscall } {
 		continue
 	    }
 
+	    if { $displaced == "on" && $syscall == "clone" } {
+		# GDB doesn't support stepping over clone syscall with
+		# displaced stepping.
+		kfail "gdb/19675" "single step over clone"
+		continue
+	    }
+
 	    set ret [setup $syscall]
 
 	    set syscall_insn_addr [lindex $ret 0]
@@ -193,6 +200,18 @@ proc break_cond_on_syscall { syscall } {
 	gdb_test "break \*$syscall_insn_addr if main == 0" \
 	    "Breakpoint \[0-9\]* at .*"
 
+	if { $syscall == "clone" } {
+	    # Create a breakpoint in the child with the condition that
+	    # evals false, so that GDBserver can get the event from the
+	    # child but GDB doesn't see it.  In this way, we don't have
+	    # to adjust the test flow for "clone".
+	    # This is a regression test for PR server/19736.  In this way,
+	    # we can test that GDBserver gets an event from the child and
+	    # set suspend count correctly while the parent is stepping over
+	    # the breakpoint.
+	    gdb_test "break clone_fn if main == 0"
+	}
+
 	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
 	    "continue to marker ($syscall)"
@@ -201,6 +220,7 @@ proc break_cond_on_syscall { syscall } {
 
 step_over_syscall "fork"
 step_over_syscall "vfork"
+step_over_syscall "clone"
 
 set testfile "step-over-fork"
 clean_restart $testfile
@@ -225,4 +245,5 @@ gdb_test_multiple $test $test {
 if { $cond_bp_target } {
     break_cond_on_syscall "fork"
     break_cond_on_syscall "vfork"
+    break_cond_on_syscall "clone"
 }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
                     ` (3 preceding siblings ...)
  2016-02-26 14:04   ` [PATCH 3/7] Step over syscalll insn with disp-step on and off Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 15:02     ` Luis Machado
  2016-02-26 14:04   ` [PATCH 6/7] Reformat gdb.base/step-over-syscall.exp Yao Qi
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

We can also extend disp-step-syscall.exp to test GDBserver step over
breakpoint on syscall instruction.  That is, we set a breakpoint
with a false condition on syscall instruction, so that GDBserver will
step over it.

This test triggers a GDBserver internal error, which can be fixed by
this series.

(gdb) PASS: gdb.base/disp-step-syscall.exp: fork: break cond on target: break on syscall insns
continue^M
Continuing.^M
Remote connection closed^M
(gdb) FAIL: gdb.base/disp-step-syscall.exp: fork: break cond on target: continue to fork again

In GDBserver, there is an internal error,

/home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
unsuspend LWP 25554, suspended=-1

the simplified reproducer is like,

$ ./gdb ./testsuite/outputs/gdb.base/disp-step-syscall/disp-step-fork
(gdb) b main
(gdb) c
(gdb) disassemble fork // in order to find the address of insn 'syscall'
....
   0x00007ffff7ad6023 <+179>:	syscall
(gdb) b *0x00007ffff7ad6023 if main == 0
(gdb) c

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp (break_cond_on_syscall): New.
	If target supports condition evaluation on target, invoke
	break_cond_on_syscall for fork and vfork.
---
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 57 ++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 3cf436d..9ecf2a5 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -168,5 +168,62 @@ proc disp_step_cross_syscall { syscall } {
     }
 }
 
+# Set a breakpoint with a condition that evals false on syscall
+# instruction.  In fact, it tests GDBserver steps over syscall
+# instruction.
+
+proc break_cond_on_syscall { syscall } {
+    with_test_prefix "break cond on target : $syscall" {
+	set testfile "disp-step-$syscall"
+
+	set ret [setup $syscall]
+
+	set syscall_insn_addr [lindex $ret 0]
+	set syscall_insn_next_addr [lindex $ret 1]
+	if { $syscall_insn_addr == -1 } {
+	    return -1
+	}
+
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	    "continue to $syscall"
+	# Delete breakpoint syscall insns to avoid interference to other syscalls.
+	delete_breakpoints
+
+
+	# Create a breakpoint with a condition that evals false.
+	gdb_test "break \*$syscall_insn_addr if main == 0" \
+	    "Breakpoint \[0-9\]* at .*"
+
+	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
+	    "continue to marker ($syscall)"
+    }
+}
+
 disp_step_cross_syscall "fork"
 disp_step_cross_syscall "vfork"
+
+set testfile "disp-step-fork"
+clean_restart $testfile
+if { ![runto main] } then {
+    fail "run to main"
+    return -1
+}
+
+set cond_bp_target 1
+
+set test "set breakpoint condition-evaluation target"
+gdb_test_multiple $test $test {
+    -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
+	# Target doesn't support breakpoint condition
+	# evaluation on its side.
+	set cond_bp_target 0
+    }
+    -re "^$test\r\n$gdb_prompt $" {
+    }
+}
+
+if { $cond_bp_target } {
+    break_cond_on_syscall "fork"
+    break_cond_on_syscall "vfork"
+}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 2/7] Refactor gdb.base/disp-step-syscall.exp for general step over test
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
  2016-02-26 14:04   ` [PATCH 7/7] New test about step over clone syscall Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 14:04   ` [PATCH 5/7] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

This patch moves some code out of disp_step_cross_syscall to a new proc
check_pc_after_cross_syscall and setup.  Procedure setup is to start a
fresh GDB and compute the syscall instruction address.

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp (check_pc_after_cross_syscall): New
	proc.
	(setup): New proc.
	(disp_step_cross_syscall): Move code to check_pc_after_cross_syscall
	and setup.
---
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 149 +++++++++++++++------------
 1 file changed, 83 insertions(+), 66 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 80cdc3b..a1af3b4 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -32,80 +32,105 @@ if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
     return -1
 }
 
-proc disp_step_cross_syscall { syscall } {
-    with_test_prefix "$syscall" {
-	global syscall_insn
-	global gdb_prompt
+proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
+    set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
+
+    set test "single step over $syscall final pc"
+    if {$syscall_insn_next_addr != 0
+	&& $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
+	pass $test
+    } else {
+	fail $test
+    }
+}
 
-	set testfile "disp-step-$syscall"
+# Restart GDB and set up the test.  Return a list in which the first one
+# is the address of syscall instruction and the second one is the address
+# of the next instruction address of syscall instruction.  If anything
+# wrong, the two elements of list are -1.
 
-	if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
-	    untested ${testfile}.exp
-	    return -1
-	}
+proc setup { syscall } {
+    global gdb_prompt syscall_insn
 
-	if { ![runto main] } then {
-	    fail "run to main ($syscall)"
-	    return
-	}
+    set testfile "disp-step-$syscall"
 
-	# Delete the breakpoint on main.
-	gdb_test_no_output "delete break 1"
+    clean_restart $testfile
 
-	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
-	gdb_test_no_output "set displaced-stepping off"
+    if { ![runto main] } then {
+	fail "run to main ($syscall)"
+	return -1
+    }
 
-	set syscall_bp 0
-	gdb_test_multiple "break $syscall"  "break $syscall" {
-	    -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
-		set syscall_bp $expect_out(1,string)
-		pass "break $syscall"
-	    }
-	}
+    # Delete the breakpoint on main.
+    gdb_test_no_output "delete break 1"
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (1st time)"
-	# Hit the breakpoint on $syscall for the first time.  In this time, we will let PLT
-	# resolution done, and the number single steps we will do later will be
-	# reduced.
+    gdb_test_no_output "set displaced-stepping off"
 
-	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
-	    "continue to $syscall (2nd time)"
-	# Hit the breakpoint on $syscall for the second time.  In this time, the address
-	# of syscall insn and next insn of syscall are recorded.
+    gdb_test "break $syscall" "Breakpoint \[0-9\]* at .*"
 
-	gdb_test "display/i \$pc" ".*"
+    gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	"continue to $syscall (1st time)"
+    # Hit the breakpoint on $syscall for the first time.  In this time,
+    # we will let PLT resolution done, and the number single steps we will
+    # do later will be reduced.
 
+    gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	"continue to $syscall (2nd time)"
+    # Hit the breakpoint on $syscall for the second time.  In this time,
+    # the address of syscall insn and next insn of syscall are recorded.
 
-	# Single step until we see a syscall insn or we reach the
-	# upper bound of loop iterations.
-	set msg "find syscall insn in $syscall"
-	set steps 0
-	set max_steps 1000
-	gdb_test_multiple "stepi" $msg {
-	    -re ".*$syscall_insn.*$gdb_prompt $" {
-		pass $msg
-	    }
-	    -re "x/i .*=>.*\r\n$gdb_prompt $" {
-		incr steps
-		if {$steps == $max_steps} {
-		    fail $msg
-		} else {
-		    send_gdb "stepi\n"
-		    exp_continue
-		}
+    gdb_test "display/i \$pc" ".*"
+
+    # Single step until we see a syscall insn or we reach the
+    # upper bound of loop iterations.
+    set msg "find syscall insn in $syscall"
+    set steps 0
+    set max_steps 1000
+    gdb_test_multiple "stepi" $msg {
+	-re ".*$syscall_insn.*$gdb_prompt $" {
+	    pass $msg
+	}
+	-re "x/i .*=>.*\r\n$gdb_prompt $" {
+	    incr steps
+	    if {$steps == $max_steps} {
+		fail $msg
+	    } else {
+		send_gdb "stepi\n"
+		exp_continue
 	    }
 	}
+    }
+
+    if {$steps == $max_steps} {
+	return { -1, -1 }
+    }
+
+    set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
+    if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
+	return { -1, -1 }
+    }
+    return [list $syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]]
+}
 
-	if {$steps == $max_steps} {
+proc disp_step_cross_syscall { syscall } {
+    with_test_prefix "$syscall" {
+	global syscall_insn
+	global gdb_prompt
+
+	set testfile "disp-step-$syscall"
+
+	if [build_executable ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
+	    untested ${testfile}.exp
 	    return -1
 	}
 
-	set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
-	if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
+	set ret [setup $syscall]
+
+	set syscall_insn_addr [lindex $ret 0]
+	set syscall_insn_next_addr [lindex $ret 1]
+	if { $syscall_insn_addr == -1 } {
 	    return -1
 	}
-	set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"]
 
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
 	    "continue to $syscall (3rd time)"
@@ -120,7 +145,6 @@ proc disp_step_cross_syscall { syscall } {
 		pass "break on syscall insns"
 	    }
 	}
-	gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
 
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
 	    "continue to syscall insn $syscall"
@@ -132,19 +156,12 @@ proc disp_step_cross_syscall { syscall } {
 	    return -1
 	}
 
-	set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
-
-	set test "single step over $syscall final pc"
-	if {$syscall_insn_next_addr != 0
-	    && $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
-	    pass $test
-	} else {
-	    fail $test
-	}
+	check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
 
 	# Delete breakpoint syscall insns to avoid interference to other syscalls.
-	gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn"
+	delete_breakpoints
 
+	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
 	    "continue to marker ($syscall)"
     }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3/7] Step over syscalll insn with disp-step on and off
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
                     ` (2 preceding siblings ...)
  2016-02-26 14:04   ` [PATCH 5/7] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-02-26 14:04   ` [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver Yao Qi
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

disp-step-syscall.exp was added to test displaced stepping over syscall
instructions, in which we set breakpoint on syscall instruction, and
step over it.  In fact, we can extend the test to non-displaced-stepping
case.  This patch wraps the test with displaced stepping on and off.
Note that the indentation and format isn't adjusted here to make this
patch easy to read.  The following patch will fix the format separately.

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp: Don't invoke
	support_displaced_stepping.
	(disp_step_cross_syscall): Test with displaced stepping off and
	on if supported.
---
 gdb/testsuite/gdb.base/disp-step-syscall.exp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index a1af3b4..3cf436d 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -15,11 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-if { ![support_displaced_stepping] } {
-    unsupported "displaced stepping"
-    return -1
-}
-
 set syscall_insn ""
 
 # Define the syscall instruction for each target.
@@ -124,6 +119,11 @@ proc disp_step_cross_syscall { syscall } {
 	    return -1
 	}
 
+	foreach_with_prefix displaced {"off" "on"} {
+	    if {$displaced == "on" && ![support_displaced_stepping]} {
+		continue
+	    }
+
 	set ret [setup $syscall]
 
 	set syscall_insn_addr [lindex $ret 0]
@@ -149,7 +149,7 @@ proc disp_step_cross_syscall { syscall } {
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
 	    "continue to syscall insn $syscall"
 
-	gdb_test_no_output "set displaced-stepping on"
+	gdb_test_no_output "set displaced-stepping $displaced"
 
 	# Check the address of next instruction of syscall.
 	if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
@@ -164,6 +164,7 @@ proc disp_step_cross_syscall { syscall } {
 	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
 	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
 	    "continue to marker ($syscall)"
+	}
     }
 }
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/7] [GDBserver] Leave child suspended when step over parent
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
                     ` (5 preceding siblings ...)
  2016-02-26 14:04   ` [PATCH 6/7] Reformat gdb.base/step-over-syscall.exp Yao Qi
@ 2016-02-26 14:04   ` Yao Qi
  2016-03-03  9:21   ` [PATCH 0/7 V2] " Yao Qi
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 14:04 UTC (permalink / raw)
  To: gdb-patches

I see the following GDBserver internal error in two cases,

 gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
 unsuspend LWP 17200, suspended=-1

 1. step over a breakpoint on fork/vfork syscall instruction,
 2. step over a breakpoint on clone syscall instruction and child
    threads hits a breakpoint,

the stack backtrace is

 #0  internal_error (file=file@entry=0x44c4c0 "gdb/gdbserver/linux-low.c", line=line@entry=1922,
    fmt=fmt@entry=0x44c7d0 "unsuspend LWP %ld, suspended=%d\n") at gdb/gdbserver/../common/errors.c:51
 #1  0x0000000000424014 in lwp_suspended_decr (lwp=<optimised out>, lwp=<optimised out>) at gdb/gdbserver/linux-low.c:1922
 #2  0x000000000042403a in unsuspend_one_lwp (entry=<optimised out>, except=0x66e8c0) at gdb/gdbserver/linux-low.c:2885
 #3  0x0000000000405f45 in find_inferior (list=<optimised out>, func=func@entry=0x424020 <unsuspend_one_lwp>, arg=arg@entry=0x66e8c0)
    at gdb/gdbserver/inferiors.c:243
 #4  0x00000000004297de in unsuspend_all_lwps (except=0x66e8c0) at gdb/gdbserver/linux-low.c:2895
 #5  linux_wait_1 (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, target_options=target_options@entry=0)
    at gdb/gdbserver/linux-low.c:3632
 #6  0x000000000042a764 in linux_wait (ptid=..., ourstatus=0x665ec0 <last_status>, target_options=0)
    at gdb/gdbserver/linux-low.c:3770
 #7  0x0000000000411163 in mywait (ptid=..., ourstatus=ourstatus@entry=0x665ec0 <last_status>, options=options@entry=0, connected_wait=connected_wait@entry=1)
    at gdb/gdbserver/target.c:214
 #8  0x000000000040b1f2 in resume (actions=0x66f800, num_actions=1) at gdb/gdbserver/server.c:2757
 #9  0x000000000040f660 in handle_v_cont (own_buf=0x66a630 "vCont;c:p45e9.-1") at gdb/gdbserver/server.c:2719

when GDBserver steps over a thread, other threads have been suspended,
the "stepping" thread may create new thread, but GDBserver doesn't set
it suspend count to 1.  When GDBserver unsuspend threads, the child's
suspend count goes to -1, and the assert is triggered.  In fact, GDBserver
has already taken care of suspend count of new thread when GDBserver is
suspending all threads except the one GDBserver wants to step over by
https://sourceware.org/ml/gdb-patches/2015-07/msg00946.html

+	  /* If we're suspending all threads, leave this one suspended
+	     too.  */
+	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+	    {
+	      if (debug_threads)
+		debug_printf ("HEW: leaving child suspended\n");
+	      child_lwp->suspended = 1;
+	    }

but that is not enough, because new thread is still can be spawned in
the thread which is being stepped over.  This patch extends the
condition that GDBserver set child's suspend count to one if it is
suspending threads or stepping over the thread.

gdb/gdbserver:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	PR server/19736
	* linux-low.c (handle_extended_wait): Set child suspended
	if event_lwp->bp_reinsert isn't zero.
---
 gdb/gdbserver/linux-low.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 528147f..34bd28b 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -529,8 +529,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 	  child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
 
 	  /* If we're suspending all threads, leave this one suspended
-	     too.  */
-	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+	     too.  If the fork/clone parent is stepping over a breakpoint,
+	     all other threads have been suspended already.  Leave the
+	     child suspended too.  */
+	  if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
+	      || event_lwp->bp_reinsert != 0)
 	    {
 	      if (debug_threads)
 		debug_printf ("HEW: leaving child suspended\n");
@@ -583,9 +586,12 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 	 before calling linux_resume_one_lwp.  */
       new_lwp->stopped = 1;
 
-     /* If we're suspending all threads, leave this one suspended
-	too.  */
-      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+      /* If we're suspending all threads, leave this one suspended
+	 too.  If the fork/clone parent is stepping over a breakpoint,
+	 all other threads have been suspended already.  Leave the
+	 child suspended too.  */
+      if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
+	  || event_lwp->bp_reinsert != 0)
 	new_lwp->suspended = 1;
 
       /* Normally we will get the pending SIGSTOP.  But in some cases
-- 
1.9.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver
  2016-02-26 14:04   ` [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver Yao Qi
@ 2016-02-26 15:02     ` Luis Machado
  2016-02-26 15:50       ` Yao Qi
  0 siblings, 1 reply; 30+ messages in thread
From: Luis Machado @ 2016-02-26 15:02 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 02/26/2016 11:03 AM, Yao Qi wrote:
> We can also extend disp-step-syscall.exp to test GDBserver step over
> breakpoint on syscall instruction.  That is, we set a breakpoint
> with a false condition on syscall instruction, so that GDBserver will
> step over it.
>
> This test triggers a GDBserver internal error, which can be fixed by
> this series.
>
> (gdb) PASS: gdb.base/disp-step-syscall.exp: fork: break cond on target: break on syscall insns
> continue^M
> Continuing.^M
> Remote connection closed^M
> (gdb) FAIL: gdb.base/disp-step-syscall.exp: fork: break cond on target: continue to fork again
>
> In GDBserver, there is an internal error,
>
> /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
> unsuspend LWP 25554, suspended=-1
>
> the simplified reproducer is like,
>
> $ ./gdb ./testsuite/outputs/gdb.base/disp-step-syscall/disp-step-fork
> (gdb) b main
> (gdb) c
> (gdb) disassemble fork // in order to find the address of insn 'syscall'
> ....
>     0x00007ffff7ad6023 <+179>:	syscall
> (gdb) b *0x00007ffff7ad6023 if main == 0
> (gdb) c
>
> gdb/testsuite:
>
> 2016-02-26  Yao Qi  <yao.qi@linaro.org>
>
> 	* gdb.base/disp-step-syscall.exp (break_cond_on_syscall): New.
> 	If target supports condition evaluation on target, invoke
> 	break_cond_on_syscall for fork and vfork.
> ---
>   gdb/testsuite/gdb.base/disp-step-syscall.exp | 57 ++++++++++++++++++++++++++++
>   1 file changed, 57 insertions(+)
>
> diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
> index 3cf436d..9ecf2a5 100644
> --- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
> +++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
> @@ -168,5 +168,62 @@ proc disp_step_cross_syscall { syscall } {
>       }
>   }
>
> +# Set a breakpoint with a condition that evals false on syscall
> +# instruction.  In fact, it tests GDBserver steps over syscall
> +# instruction.
> +
> +proc break_cond_on_syscall { syscall } {
> +    with_test_prefix "break cond on target : $syscall" {
> +	set testfile "disp-step-$syscall"
> +
> +	set ret [setup $syscall]
> +
> +	set syscall_insn_addr [lindex $ret 0]
> +	set syscall_insn_next_addr [lindex $ret 1]
> +	if { $syscall_insn_addr == -1 } {
> +	    return -1
> +	}
> +
> +	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
> +	    "continue to $syscall"
> +	# Delete breakpoint syscall insns to avoid interference to other syscalls.
> +	delete_breakpoints

"... interference with ..."

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver
  2016-02-26 15:02     ` Luis Machado
@ 2016-02-26 15:50       ` Yao Qi
  0 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-02-26 15:50 UTC (permalink / raw)
  To: Luis Machado; +Cc: Yao Qi, gdb-patches

Luis Machado <lgustavo@codesourcery.com> writes:

>> +	# Delete breakpoint syscall insns to avoid interference to other syscalls.
>> +	delete_breakpoints
>
> "... interference with ..."

Oops, I thought I fixed that to address your comment to v1.  Sorry about that.

-- 
Yao (齐尧)

From 6fb354c27d4469e1b7b4ef3b94f74763cf6dd1e1 Mon Sep 17 00:00:00 2001
From: Yao Qi <yao.qi@linaro.org>
Date: Thu, 18 Feb 2016 12:39:57 +0000
Subject: [PATCH] Step over fork/vfork syscall insn in gdbserver

We can also extend disp-step-syscall.exp to test GDBserver step over
breakpoint on syscall instruction.  That is, we set a breakpoint
with a false condition on syscall instruction, so that GDBserver will
step over it.

This test triggers a GDBserver internal error, which can be fixed by
this series.

(gdb) PASS: gdb.base/disp-step-syscall.exp: fork: break cond on target: break on syscall insns
continue^M
Continuing.^M
Remote connection closed^M
(gdb) FAIL: gdb.base/disp-step-syscall.exp: fork: break cond on target: continue to fork again

In GDBserver, there is an internal error,

/home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected.
unsuspend LWP 25554, suspended=-1

the simplified reproducer is like,

$ ./gdb ./testsuite/outputs/gdb.base/disp-step-syscall/disp-step-fork
(gdb) b main
(gdb) c
(gdb) disassemble fork // in order to find the address of insn 'syscall'
....
   0x00007ffff7ad6023 <+179>:	syscall
(gdb) b *0x00007ffff7ad6023 if main == 0
(gdb) c

gdb/testsuite:

2016-02-26  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/disp-step-syscall.exp (break_cond_on_syscall): New.
	If target supports condition evaluation on target, invoke
	break_cond_on_syscall for fork and vfork.

diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index 3cf436d..0aac649 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -168,5 +168,62 @@ proc disp_step_cross_syscall { syscall } {
     }
 }
 
+# Set a breakpoint with a condition that evals false on syscall
+# instruction.  In fact, it tests GDBserver steps over syscall
+# instruction.
+
+proc break_cond_on_syscall { syscall } {
+    with_test_prefix "break cond on target : $syscall" {
+	set testfile "disp-step-$syscall"
+
+	set ret [setup $syscall]
+
+	set syscall_insn_addr [lindex $ret 0]
+	set syscall_insn_next_addr [lindex $ret 1]
+	if { $syscall_insn_addr == -1 } {
+	    return -1
+	}
+
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+	    "continue to $syscall"
+	# Delete breakpoint syscall insns to avoid interference with other syscalls.
+	delete_breakpoints
+
+
+	# Create a breakpoint with a condition that evals false.
+	gdb_test "break \*$syscall_insn_addr if main == 0" \
+	    "Breakpoint \[0-9\]* at .*"
+
+	gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
+	gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
+	    "continue to marker ($syscall)"
+    }
+}
+
 disp_step_cross_syscall "fork"
 disp_step_cross_syscall "vfork"
+
+set testfile "disp-step-fork"
+clean_restart $testfile
+if { ![runto main] } then {
+    fail "run to main"
+    return -1
+}
+
+set cond_bp_target 1
+
+set test "set breakpoint condition-evaluation target"
+gdb_test_multiple $test $test {
+    -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
+	# Target doesn't support breakpoint condition
+	# evaluation on its side.
+	set cond_bp_target 0
+    }
+    -re "^$test\r\n$gdb_prompt $" {
+    }
+}
+
+if { $cond_bp_target } {
+    break_cond_on_syscall "fork"
+    break_cond_on_syscall "vfork"
+}

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/7 V2] Leave child suspended when step over parent
  2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
                     ` (6 preceding siblings ...)
  2016-02-26 14:04   ` [PATCH 1/7] [GDBserver] Leave child suspended when step over parent Yao Qi
@ 2016-03-03  9:21   ` Yao Qi
  7 siblings, 0 replies; 30+ messages in thread
From: Yao Qi @ 2016-03-03  9:21 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi <qiyaoltc@gmail.com> writes:

> Here is the v2 of this patch series.  V1 can be found
> https://sourceware.org/ml/gdb-patches/2016-02/msg00591.html
>
> The changes in v2 are:
>
>  1. Remove patch "Use loop in disp-step-fork.c and disp-step-vfork.c"
>     from this series,
>  2. Open PR server/19736 for the bug this series fixes, and mention
>     this PR in the comments of tests,
>  3. Restart GDB in each test instead of doing multiple tests in a
>     single debugging session,
>  4. Fix some wording issues in the comments.
>  5. Use foreach_with_prefix,

Patches are pushed in.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2016-03-03  9:21 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-19 14:36 [PATCH 0/8] Leave child suspended when step over parent Yao Qi
2016-02-19 14:36 ` [PATCH 4/8] Step over syscalll insn with disp-step on and off Yao Qi
2016-02-25 17:27   ` Pedro Alves
2016-02-19 14:36 ` [PATCH 2/8] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
2016-02-19 14:36 ` [PATCH 5/8] Step over fork/vfork syscall insn in gdbserver Yao Qi
2016-02-23 20:28   ` Luis Machado
2016-02-25 17:31   ` Pedro Alves
2016-02-19 14:36 ` [PATCH 3/8] Use loop in disp-step-fork.c and disp-step-vfork.c Yao Qi
2016-02-25 17:28   ` Pedro Alves
2016-02-19 14:37 ` [PATCH 6/8] Reformat disp-step-syscall.exp Yao Qi
2016-02-19 14:37 ` [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Yao Qi
2016-02-23 20:23   ` Luis Machado
2016-02-25 17:12   ` Pedro Alves
2016-02-19 14:37 ` [PATCH 8/8] New test about step over clone syscall Yao Qi
2016-02-23 20:31   ` Luis Machado
2016-02-25 17:43   ` Pedro Alves
2016-02-25 17:43   ` Pedro Alves
2016-02-19 14:37 ` [PATCH 7/8] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
2016-02-25 17:32   ` Pedro Alves
2016-02-26 14:03 ` [PATCH 0/7 V2] Leave child suspended when step over parent Yao Qi
2016-02-26 14:04   ` [PATCH 7/7] New test about step over clone syscall Yao Qi
2016-02-26 14:04   ` [PATCH 2/7] Refactor gdb.base/disp-step-syscall.exp for general step over test Yao Qi
2016-02-26 14:04   ` [PATCH 5/7] Rename disp-step-syscall.exp to step-over-syscall.exp Yao Qi
2016-02-26 14:04   ` [PATCH 3/7] Step over syscalll insn with disp-step on and off Yao Qi
2016-02-26 14:04   ` [PATCH 4/7] Step over fork/vfork syscall insn in gdbserver Yao Qi
2016-02-26 15:02     ` Luis Machado
2016-02-26 15:50       ` Yao Qi
2016-02-26 14:04   ` [PATCH 6/7] Reformat gdb.base/step-over-syscall.exp Yao Qi
2016-02-26 14:04   ` [PATCH 1/7] [GDBserver] Leave child suspended when step over parent Yao Qi
2016-03-03  9:21   ` [PATCH 0/7 V2] " Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).