[pushed] Test gdb.threads/forking-threads-plus-breakpoint.exp with, displaced stepping off (Re: [PATCH 1/3] PR remote/19496, internal err forking-threads-plus-bkpt)

Message ID 56AFB165.8000808@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Feb. 1, 2016, 7:26 p.m. UTC
  On 01/28/2016 12:48 AM, Don Breazeal wrote:

> The cause of the problem was the following sequence of events:
> 
> * GDB knows only about the main thread
> 
> * the first fork event is reported to GDB, saved as pending_event
> 
> * qXfer:threads_read gets the threads from the remote.
>   remove_new_fork_children id's the fork child from the pending event
>   and removes it from the list reported to GDB.  All the rest of the
>   threads, including the fork parent, are added to the GDB thread list.
> 
> * GDB stops all the threads.  All the stop events are pushed onto the
>   stop reply queue behind the pending fork event.

As this is a non-stop test, if GDB is stopping all the threads, then it
must be that your arch doesn't support displaced stepping (which is true).

By forcing displaced stepping off, I see the same internal error on x86.

I've pushed the testsuite change below to expose the problem.

Haven't managed to look at your fix in detail yet.

From 6b2e4f10aeb64868720de06d3b2da3cc2d908f10 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Mon, 1 Feb 2016 18:48:04 +0000
Subject: [PATCH] Test gdb.threads/forking-threads-plus-breakpoint.exp with
 displaced stepping off

This exposes the internal error Don mentioned in PR19496:

  (1) internal error --  gdb/target.c:2713: internal-error: Can't determine the current address space of thread

More analysis here:

  https://sourceware.org/ml/gdb-patches/2016-01/msg00685.html

The (now kfailed) internal error looks like:

 continue &
 Continuing.
 (gdb) PASS: gdb.threads/forking-threads-plus-breakpoint.exp: cond_bp_target=1: detach_on_fork=on: displaced=off: continue &
 [New Thread 2846.2847]
 (...)
 [New Thread 2867.2867]
 /home/pedro/gdb/mygit/src/gdb/target.c:2723: internal-error: Can't determine the current address space of thread Thread 2846.2846

 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 Quit this debugging session? (y or n) KFAIL: gdb.threads/forking-threads-plus-breakpoint.exp: cond_bp_target=1: detach_on_fork=on: displaced=off: inferior 1 exited (GDB internal error) (PRMS: remote/19496)
 Resyncing due to internal error.

gdb/testsuite/ChangeLog:
2016-02-01  Pedro Alves  <palves@redhat.com>

	PR remote/19496
	* gdb.threads/forking-threads-plus-breakpoint.exp
	(displaced_stepping_supported): New global.
	(probe_displaced_stepping_support): New procedure.
	(do_test): Add 'displaced' parameter, and use it.
	(top level): Check for displaced stepping support.  Add displaced
	stepping on/off testing axis.
---
 gdb/testsuite/ChangeLog                            |  9 ++++
 .../forking-threads-plus-breakpoint.exp            | 63 ++++++++++++++++++++--
 2 files changed, 67 insertions(+), 5 deletions(-)
  

Patch

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6af0e48..fb64674 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@ 
+2016-02-01  Pedro Alves  <palves@redhat.com>
+
+	* gdb.threads/forking-threads-plus-breakpoint.exp
+	(displaced_stepping_supported): New global.
+	(probe_displaced_stepping_support): New procedure.
+	(do_test): Add 'displaced' parameter, and use it.
+	(top level): Check for displaced stepping support.  Add displaced
+	stepping on/off testing axis.
+
 2016-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.mi/mi-vla-fortran.exp: Add XFAIL for accessing unassociated
diff --git a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
index b5f7c21..6c72061 100644
--- a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
+++ b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
@@ -24,13 +24,49 @@  if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}] =
     return -1
 }
 
+# Assume yes.
+set displaced_stepping_supported 1
+
+# "set displaced on" only tells gdb to use displaced stepping if
+# possible.  Probe for actual support.
+
+proc probe_displaced_stepping_support {} {
+    global displaced_stepping_supported
+    global binfile gdb_prompt
+
+    with_test_prefix "probe displaced-stepping support" {
+	clean_restart $binfile
+
+	gdb_test_no_output "set displaced on"
+	if ![runto_main] then {
+	    fail "Can't run to main"
+	    return 0
+	}
+
+	# We're stopped at the main breakpoint.  If displaced stepping is
+	# supported, we'll see related debug output while we step past
+	# that breakpoint.
+	gdb_test_no_output "set debug displaced 1"
+	gdb_test_multiple "next" "probe" {
+	    -re "displaced pc to.*$gdb_prompt $" {
+		pass "supported"
+	    }
+	    -re ".*$gdb_prompt $" {
+		set displaced_stepping_supported 0
+		pass "not supported"
+	    }
+	}
+    }
+}
+
 # The test proper.  If COND_BP_TARGET is true, then test with
 # conditional breakpoints evaluated on the target side, if possible.
 # DETACH_ON_FORK is used as value for the "set detach-on-fork"
 # setting.  If "on", this exercises GDB explicitly continuing the fork
 # child until exit.  If "off", this exercises GDB detaching the fork
-# child.
-proc do_test { cond_bp_target detach_on_fork } {
+# child.  DISPLACED indicates whether to use displaced stepping or
+# not.
+proc do_test { cond_bp_target detach_on_fork displaced } {
     global GDBFLAGS
     global srcfile testfile binfile
     global decimal gdb_prompt
@@ -48,6 +84,7 @@  proc do_test { cond_bp_target detach_on_fork } {
     }
 
     gdb_test_no_output "set detach-on-fork $detach_on_fork"
+    gdb_test_no_output "set displaced $displaced"
 
     gdb_test "break $linenum if zero == 1" \
 	"Breakpoint .*" \
@@ -63,6 +100,12 @@  proc do_test { cond_bp_target detach_on_fork } {
     set fork_count 0
     set ok 0
 
+    if {$displaced == "off"
+	&& [target_info exists gdb_protocol]
+	&& ([target_info gdb_protocol] == "remote"
+	    || [target_info gdb_protocol] == "extended-remote")} {
+	setup_kfail "remote/19496" *-*-*
+    }
     set test "inferior 1 exited"
     gdb_test_multiple "" $test {
 	-re "Inferior 1 \(\[^\r\n\]+\) exited normally" {
@@ -92,14 +135,24 @@  proc do_test { cond_bp_target detach_on_fork } {
 	"only inferior 1 left"
 }
 
+probe_displaced_stepping_support
+
 foreach_with_prefix cond_bp_target {1 0} {
     foreach_with_prefix detach_on_fork {"on" "off"} {
-	do_test $cond_bp_target $detach_on_fork
-
 	# Disable "off" for now.  The test does pass with
 	# detach-on-fork off (at the time of writing), but gdb seems
 	# to slow down quadratically as inferiors are created, and
 	# then the test takes annoyingly long to complete...
-	break
+	if {$detach_on_fork == "off"} {
+	    continue
+	}
+
+	foreach_with_prefix displaced {"on" "off"} {
+	    if {$displaced == "on" && !$displaced_stepping_supported} {
+		continue
+	    }
+
+	    do_test $cond_bp_target $detach_on_fork $displaced
+	}
     }
 }