public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/8] record: do not allow record goto on a running thread
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
@ 2016-07-06 11:56 ` Markus Metzger
  2016-07-06 11:56 ` [PATCH 4/8] record: signal a record goto stop to front-ends Markus Metzger
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

We can't start replaying if the selected thread is currently running.  Throw an
error in this case.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record.c: Include gdbthread.h
	(require_not_running): New.
	(record_goto, cmd_record_goto_begin, cmd_record_goto_end): Call
	require_not_running.


---
 gdb/record.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/gdb/record.c b/gdb/record.c
index 1af134f..ef15459 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -26,6 +26,7 @@
 #include "common/common-utils.h"
 #include "cli/cli-utils.h"
 #include "disasm.h"
+#include "gdbthread.h"
 
 #include <ctype.h>
 
@@ -80,6 +81,16 @@ require_record_target (void)
   return t;
 }
 
+/* Check that the inferior thread is not running.  Throw an error if it is.  */
+
+static void
+require_not_running (void)
+{
+  if (is_running (inferior_ptid))
+    error (_("Cannot execute this command while "
+	     "the selected thread is running."));
+}
+
 /* See record.h.  */
 
 void
@@ -342,6 +353,7 @@ record_goto (const char *arg)
   insn = parse_and_eval_long (arg);
 
   require_record_target ();
+  require_not_running ();
   target_goto_record (insn);
 }
 
@@ -365,6 +377,7 @@ cmd_record_goto_begin (char *arg, int from_tty)
     error (_("Junk after argument: %s."), arg);
 
   require_record_target ();
+  require_not_running ();
   target_goto_record_begin ();
 }
 
@@ -377,6 +390,7 @@ cmd_record_goto_end (char *arg, int from_tty)
     error (_("Junk after argument: %s."), arg);
 
   require_record_target ();
+  require_not_running ();
   target_goto_record_end ();
 }
 
-- 
1.8.3.1

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

* [PATCH 0/8] record: notify about "record goto" stop
@ 2016-07-06 11:56 Markus Metzger
  2016-07-06 11:56 ` [PATCH 2/8] record: do not allow record goto on a running thread Markus Metzger
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

The "record goto" command moves the selected thread in the recorded execution
history.  It does not send a stopped notification so the move is not visible to
MI consumers.

For the record-btrace target, the "record stop" command moves all replaying
threads to the end of their respective execution history.  It again does not
send a stopped notification so the move goes unnoticed.

The issue has been reported and discussed here:
https://sourceware.org/ml/gdb/2016-06/msg00005.html.

This series attempts to fix it.  See also branch users/mmetzger/record-goto-mi.

Markus Metzger (8):
  btrace: check if we're replaying when setting the replay position to
    the end
  record: do not allow record goto on a running thread
  infrun: export clear_proceed_status_thread
  record: signal a record goto stop to front-ends
  mi, testsuite: add another EXTRA option to mi_expect_stop
  record-full: signal record-goto stop
  btrace-btrace: signal record-goto stop
  btrace: record stop moves to the end of the trace

 gdb/infrun.c                             |  5 +--
 gdb/infrun.h                             |  3 ++
 gdb/record-btrace.c                      | 74 +++++++++++++++++++++++++++++---
 gdb/record-full.c                        |  2 +-
 gdb/record.c                             | 35 +++++++++++++++
 gdb/record.h                             |  3 ++
 gdb/testsuite/gdb.btrace/non-stop.c      |  6 ++-
 gdb/testsuite/gdb.btrace/non-stop.exp    | 19 +++++++-
 gdb/testsuite/gdb.btrace/record_goto.exp |  3 ++
 gdb/testsuite/gdb.btrace/stop.exp        | 70 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/mi-reverse.exp      |  9 ++++
 gdb/testsuite/lib/mi-support.exp         | 26 +++++++----
 12 files changed, 233 insertions(+), 22 deletions(-)
 create mode 100644 gdb/testsuite/gdb.btrace/stop.exp

-- 
1.8.3.1

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

* [PATCH 4/8] record: signal a record goto stop to front-ends
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
  2016-07-06 11:56 ` [PATCH 2/8] record: do not allow record goto on a running thread Markus Metzger
@ 2016-07-06 11:56 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 6/8] record-full: signal record-goto stop Markus Metzger
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

The "record goto" command does not indicate the stop to front-ends.  Instead,
it prints the new location directly.

Add a function to signal a normal stop to observers and have them print the new
location.  This function temporarily switches to the stopped thread.

We use the TARGET_WAITKIND_NO_RESUMED wait status for this purpose.  This should
result in a stop notification without giving a stop reason.  We could also
invent a new wait status but this doesn't seem necessary at this point.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record.h (record_signal_goto_stop): New.
	* record.c (record_signal_goto_stop): New.


---
 gdb/record.c | 21 +++++++++++++++++++++
 gdb/record.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/gdb/record.c b/gdb/record.c
index ef15459..15bc722 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -343,6 +343,27 @@ cmd_record_save (char *args, int from_tty)
 /* See record.h.  */
 
 void
+record_signal_goto_stop (struct thread_info *tp)
+{
+  struct target_waitstatus ws;
+  struct cleanup *cleanup;
+
+  clear_proceed_status_thread (tp);
+
+  cleanup = make_cleanup_restore_current_thread ();
+  switch_to_thread (tp->ptid);
+
+  ws.kind = TARGET_WAITKIND_NO_RESUMED;
+  set_last_target_status (tp->ptid, ws);
+
+  observer_notify_normal_stop (NULL, 1);
+
+  do_cleanups (cleanup);
+}
+
+/* See record.h.  */
+
+void
 record_goto (const char *arg)
 {
   ULONGEST insn;
diff --git a/gdb/record.h b/gdb/record.h
index 84440c64..8baf01c 100644
--- a/gdb/record.h
+++ b/gdb/record.h
@@ -91,4 +91,7 @@ extern struct target_ops *find_record_target (void);
    it does anything.  */
 extern void record_preopen (void);
 
+/* Signal a record-goto stop of TP to front-ends.  */
+extern void record_signal_goto_stop (struct thread_info *tp);
+
 #endif /* _RECORD_H_ */
-- 
1.8.3.1

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

* [PATCH 5/8] mi, testsuite: add another EXTRA option to mi_expect_stop
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
                   ` (6 preceding siblings ...)
  2016-07-06 11:57 ` [PATCH 3/8] infrun: export clear_proceed_status_thread Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

Allow the EXTRA argument of mi_expect_stop to contain a third pattern that must
occur directly before the GDB prompt at the end of the output.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

testsuite/
	* lib/mi-support.exp (mi_expect_stop): Add third EXTRA field.


---
 gdb/testsuite/lib/mi-support.exp | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 28af70a..4c17501 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1127,6 +1127,8 @@ proc mi_detect_async {} {
 # output right after *stopped, and the second element is output
 # right after reason field.  The regex after reason should not include
 # the comma separating it from the following fields.
+# If EXTRA is a list of three elements, the first two are for the above
+# and the third element is for output right before GDB prompt.
 #
 # When we fail to match output at all, -1 is returned.  If FILE does
 # match and the target system has no debug info for FILE return 0.
@@ -1150,7 +1152,15 @@ proc mi_expect_stop { reason func args file line extra test } {
 
     set after_stopped ""
     set after_reason ""
-    if { [llength $extra] == 2 } {
+    set before_prompt ""
+    if { [llength $extra] == 3 } {
+	set after_stopped [lindex $extra 0]
+	set after_reason [lindex $extra 1]
+		if { $after_reason != "" } {
+			set after_reason "${after_reason},"
+		}
+	set before_prompt [lindex $extra 2]
+    } elseif { [llength $extra] == 2 } {
 	set after_stopped [lindex $extra 0]
 	set after_reason [lindex $extra 1]
 	set after_reason "${after_reason},"
@@ -1166,7 +1176,7 @@ proc mi_expect_stop { reason func args file line extra test } {
 
     if { $reason == "really-no-reason" } {
 	gdb_expect {
-	    -re "\\*stopped\r\n$prompt_re" {
+	    -re "\\*stopped\r\n$before_prompt$prompt_re" {
 		pass "$test"
 	    }
 	    timeout {
@@ -1179,7 +1189,7 @@ proc mi_expect_stop { reason func args file line extra test } {
     if { $reason == "exited-normally" } {
 
 	gdb_expect {
-	    -re "\\*stopped,reason=\"exited-normally\"\r\n$prompt_re" {
+	    -re "\\*stopped,reason=\"exited-normally\"\r\n$before_prompt$prompt_re" {
 		pass "$test"
 	    }
 	    -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"}
@@ -1191,7 +1201,7 @@ proc mi_expect_stop { reason func args file line extra test } {
     }
     if { $reason == "exited" } {
 	gdb_expect {
-	    -re "\\*stopped,reason=\"exited\",exit-code=\"\[0-7\]+\"\r\n$prompt_re" {
+	    -re "\\*stopped,reason=\"exited\",exit-code=\"\[0-7\]+\"\r\n$before_prompt$prompt_re" {
 		pass "$test"
 	    }
 	    -re ".*$mi_gdb_prompt$" {
@@ -1205,7 +1215,7 @@ proc mi_expect_stop { reason func args file line extra test } {
     }
 
     if { $reason == "solib-event" } {
-	set pattern "\\*stopped,reason=\"solib-event\",thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re"
+	set pattern "\\*stopped,reason=\"solib-event\",thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$before_prompt$prompt_re"
 	verbose -log "mi_expect_stop: expecting: $pattern"
 	gdb_expect {
 	    -re "$pattern" {
@@ -1235,9 +1245,9 @@ proc mi_expect_stop { reason func args file line extra test } {
 
     set a $after_reason
 
-    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re"
+    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$before_prompt$prompt_re"
     gdb_expect {
-	-re "\\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" {
+	-re "\\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$before_prompt$prompt_re" {
 	    pass "$test"
 	    if {[array names expect_out "2,string"] != ""} {
 		return $expect_out(2,string)
@@ -1245,7 +1255,7 @@ proc mi_expect_stop { reason func args file line extra test } {
 	    # No debug info available but $file does match.
 	    return 0
 	}
-	-re "\\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$any\",args=\[\\\[\{\]$any\[\\\]\}\],file=\"$any\",fullname=\"${fullname_syntax}$any\",line=\"\[0-9\]*\"\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" {
+	-re "\\*stopped,${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$any\",args=\[\\\[\{\]$any\[\\\]\}\],file=\"$any\",fullname=\"${fullname_syntax}$any\",line=\"\[0-9\]*\"\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$before_prompt$prompt_re" {
 	    verbose -log "got $expect_out(buffer)"
 	    fail "$test (stopped at wrong place)"
 	    return -1
-- 
1.8.3.1

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

* [PATCH 1/8] btrace: check if we're replaying when setting the replay position to the end
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
                   ` (2 preceding siblings ...)
  2016-07-06 11:57 ` [PATCH 6/8] record-full: signal record-goto stop Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 8/8] btrace: record stop moves to the end of the trace Markus Metzger
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

When setting the replay position to the end there is nothing to do if we are
not replaying.  Check that and return immediately.

This avoids printing the current location if we're already at the end.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record-btrace.c (record_btrace_set_replay): Check if replaying.

testsuite/
	* gdb.btrace/record_goto.exp: Test "record goto end" twice.


---
 gdb/record-btrace.c                      | 7 ++++++-
 gdb/testsuite/gdb.btrace/record_goto.exp | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 24594a9..80d9f04 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2704,7 +2704,12 @@ record_btrace_set_replay (struct thread_info *tp,
   btinfo = &tp->btrace;
 
   if (it == NULL || it->function == NULL)
-    record_btrace_stop_replaying (tp);
+    {
+      if (!btrace_is_replaying (tp))
+	return;
+
+      record_btrace_stop_replaying (tp);
+    }
   else
     {
       if (btinfo->replay == NULL)
diff --git a/gdb/testsuite/gdb.btrace/record_goto.exp b/gdb/testsuite/gdb.btrace/record_goto.exp
index 50b259a..45df261 100644
--- a/gdb/testsuite/gdb.btrace/record_goto.exp
+++ b/gdb/testsuite/gdb.btrace/record_goto.exp
@@ -160,6 +160,9 @@ gdb_test "record instruction-history -" [multi_line \
 # check that we can go to the end of the trace
 gdb_test "record goto end" ".*main \\(\\) at record_goto.c:50.*"
 
+# check that we don't repeat the current location if we go to the end again
+gdb_test_no_output "record goto end" "goto end again"
+
 # check that we're filling up the context correctly
 gdb_test "record function-call-history /ci" [multi_line \
   "14\t      fun2\tinst 35,36" \
-- 
1.8.3.1

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

* [PATCH 7/8] btrace-btrace: signal record-goto stop
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
                   ` (4 preceding siblings ...)
  2016-07-06 11:57 ` [PATCH 8/8] btrace: record stop moves to the end of the trace Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 3/8] infrun: export clear_proceed_status_thread Markus Metzger
  2016-07-06 11:57 ` [PATCH 5/8] mi, testsuite: add another EXTRA option to mi_expect_stop Markus Metzger
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

When changing a thread's replay position, call record_signal_goto_stop instead
of printing the source location directly.  This will signal the stop to
front-ends and have them print the source location.

We update the STOP_PC if the change affects the selected thread.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record-btrace.c (record_btrace_set_replay): Check ptid before updating
	STOP_PC.  Call record_signal_goto_stop.


---
 gdb/record-btrace.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 80d9f04..1998e43 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2724,8 +2724,12 @@ record_btrace_set_replay (struct thread_info *tp,
   /* Start anew from the new replay position.  */
   record_btrace_clear_histories (btinfo);
 
-  stop_pc = regcache_read_pc (get_current_regcache ());
-  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
+  /* We changed the PC of TP.  Update the global state if TP is the selected
+     thread.  */
+  if (ptid_equal (tp->ptid, inferior_ptid))
+    stop_pc = regcache_read_pc (get_current_regcache ());
+
+  record_signal_goto_stop (tp);
 }
 
 /* The to_goto_record_begin method of target record-btrace.  */
-- 
1.8.3.1

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

* [PATCH 3/8] infrun: export clear_proceed_status_thread
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
                   ` (5 preceding siblings ...)
  2016-07-06 11:57 ` [PATCH 7/8] btrace-btrace: signal record-goto stop Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 5/8] mi, testsuite: add another EXTRA option to mi_expect_stop Markus Metzger
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* infrun.h (clear_proceed_status_thread): New.
	* infrun.c (clear_proceed_status_thread): Export.


---
 gdb/infrun.c | 5 ++---
 gdb/infrun.h | 3 +++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 70a0790..5bbb649 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2785,10 +2785,9 @@ new_stop_id (void)
   current_stop_id++;
 }
 
-/* Clear out all variables saying what to do when inferior is continued.
-   First do this, then set the ones you want, then call `proceed'.  */
+/* See infrun.h.  */
 
-static void
+void
 clear_proceed_status_thread (struct thread_info *tp)
 {
   if (debug_infrun)
diff --git a/gdb/infrun.h b/gdb/infrun.h
index 39be375..e896238 100644
--- a/gdb/infrun.h
+++ b/gdb/infrun.h
@@ -80,6 +80,9 @@ extern void start_remote (int from_tty);
    step/stepi command.  */
 extern void clear_proceed_status (int step);
 
+/* Clear out the proceed status of TP.  */
+extern void clear_proceed_status_thread (struct thread_info *tp);
+
 extern void proceed (CORE_ADDR, enum gdb_signal);
 
 /* The `resume' routine should only be called in special circumstances.
-- 
1.8.3.1

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

* [PATCH 6/8] record-full: signal record-goto stop
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
  2016-07-06 11:56 ` [PATCH 2/8] record: do not allow record goto on a running thread Markus Metzger
  2016-07-06 11:56 ` [PATCH 4/8] record: signal a record goto stop to front-ends Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 1/8] btrace: check if we're replaying when setting the replay position to the end Markus Metzger
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

When changing the replay position call record_signal_goto_stop instead of
printing the new source location directly.  This will signal the stop to
front-ends and have them print the source location.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record-full.c (record_full_goto_entry): Call record_signal_goto_stop.

testsuite/
	* gdb.mi/mi-reverse.exp: Test record goto begin/end.


---
 gdb/record-full.c                   | 2 +-
 gdb/testsuite/gdb.mi/mi-reverse.exp | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/record-full.c b/gdb/record-full.c
index 0f61bcb..e875d97 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1905,7 +1905,7 @@ record_full_goto_entry (struct record_full_entry *p)
   registers_changed ();
   reinit_frame_cache ();
   stop_pc = regcache_read_pc (get_current_regcache ());
-  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
+  record_signal_goto_stop (inferior_thread ());
 }
 
 /* The "to_goto_record_begin" target method.  */
diff --git a/gdb/testsuite/gdb.mi/mi-reverse.exp b/gdb/testsuite/gdb.mi/mi-reverse.exp
index 5afeece..0fa8f8f 100644
--- a/gdb/testsuite/gdb.mi/mi-reverse.exp
+++ b/gdb/testsuite/gdb.mi/mi-reverse.exp
@@ -93,6 +93,7 @@ proc test_controlled_execution_reverse {} {
     global line_callee1_head line_callee1_body line_callee1_close
     global line_main_head    line_main_body
     global line_main_hello   line_main_callme_1
+    global line_callme_body
 
     # Test exec-reverse-finish
 
@@ -166,6 +167,14 @@ proc test_controlled_execution_reverse {} {
         "" "main" "" \
         "basics.c" $line_main_body "" \
         "reverse-continue at main"
+
+    send_gdb "record goto end\n"
+    mi_expect_stop "" "callme" "\{name=\"i\",value=\"1\"\}" "basics.c" \
+        $line_callme_body { "" "" "\\^done\r\n" } "record goto end"
+
+    send_gdb "record goto begin\n"
+    mi_expect_stop "" "main" "" "basics.c" $line_main_body \
+        { "" "" "\\^done\r\n" } "record goto begin"
 }
 
 test_controlled_execution_reverse
-- 
1.8.3.1

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

* [PATCH 8/8] btrace: record stop moves to the end of the trace
  2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
                   ` (3 preceding siblings ...)
  2016-07-06 11:57 ` [PATCH 1/8] btrace: check if we're replaying when setting the replay position to the end Markus Metzger
@ 2016-07-06 11:57 ` Markus Metzger
  2016-07-06 11:57 ` [PATCH 7/8] btrace-btrace: signal record-goto stop Markus Metzger
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Markus Metzger @ 2016-07-06 11:57 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, marc.khouzam

With the btrace record target the "record stop" command implicitly moves all
traced threads to the end of their respective history.  Unlike record full,
record btrace does not trace data and is therefore not able to resume debugging
at the current replay position.

We forgot to actually change the replay position before disabling tracing.  This
resulted in STOP_PC remaining at its old position if the current thread had been
replaying, which, in turn, resulted in GDB commands such as list or backtrace
using the wrong context.

Fix it by moving the selected thread to the end of its recorded history.
Together with the preceding patches, this will result in a front-end
notification for the selected thread if it had been replaying.  Stop replaying
other threads silently, i.e. without a front-end notification.

If the selected thread isn't replaying, notify front-ends without printing the
(unchanged) frame.  This results in a *stopped MI notification without any
thread information.

In non-stop mode, move all replaying threads to the end of their respective
histories.  This will result in a front-end notification and in the updated
location to be printed for each replaying thread.  We prefix the output with
the thread number like this:

    (gdb) record stop
    Thread 1 (Thread 0x7ffff7fcc740 (LWP 66711)) stopped replaying.
    test (arg=0x0) at gdb.btrace/multi-thread-step.c:34
    34        global = 42; /* bp.2 */
    Thread 2 (Thread 0x7ffff74fb700 (LWP 66716)) stopped replaying.
    test (arg=0x0) at gdb.btrace/multi-thread-step.c:34
    34        global = 42; /* bp.2 */
    Process record is stopped and all execution logs are deleted.

Thanks to Marc Khouzam <marc.khouzam@ericsson.com> for reporting this.

2016-07-06  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* record-btrace.c (record_btrace_set_replay)
	(record_btrace_stop_replaying): New declaration.
	(record_btrace_stop_recording): Call record_btrace_set_replay,
	record_btrace_stop_replaying, and observer_notify_normal_stop.

testsuite/
	* gdb.btrace/non-stop.exp: Test "record stop".
	* gdb.btrace/non-stop.c (test): Add statement to break at.
	* gdb.btrace/stop.exp: New.


---
 gdb/record-btrace.c                   | 59 +++++++++++++++++++++++++++--
 gdb/testsuite/gdb.btrace/non-stop.c   |  6 ++-
 gdb/testsuite/gdb.btrace/non-stop.exp | 19 +++++++++-
 gdb/testsuite/gdb.btrace/stop.exp     | 70 +++++++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 7 deletions(-)
 create mode 100644 gdb/testsuite/gdb.btrace/stop.exp

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 1998e43..7da78bc 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -97,6 +97,11 @@ static struct cmd_list_element *show_record_btrace_pt_cmdlist;
     }									\
   while (0)
 
+static void record_btrace_set_replay (struct thread_info *tp,
+				      const struct btrace_insn_iterator *it);
+
+static void record_btrace_stop_replaying (struct thread_info *tp);
+
 
 /* Update the branch trace for the current thread and return a pointer to its
    thread_info.
@@ -252,9 +257,57 @@ record_btrace_stop_recording (struct target_ops *self)
 
   record_btrace_auto_disable ();
 
-  ALL_NON_EXITED_THREADS (tp)
-    if (tp->btrace.target != NULL)
-      btrace_disable (tp);
+  /* In non-stop mode, we indicate the implicit move of each replaying thread.
+     In stop-all mode, we indicate the implicit move of the selected thread if
+     it is replaying.  Other threads are silently moved.  The MI notification
+     will indicate that all threads have been stopped which should be enough to
+     indicate this implicit move to front-ends.  */
+  if (non_stop)
+    {
+      ALL_NON_EXITED_THREADS (tp)
+	if (tp->btrace.target != NULL)
+	  {
+	    if (btrace_is_replaying (tp))
+	      {
+		printf_filtered (_("Thread %s (%s) stopped replaying.\n"),
+				 print_thread_id (tp),
+				 target_pid_to_str (tp->ptid));
+		record_btrace_set_replay (tp, NULL);
+	      }
+
+	    btrace_disable (tp);
+	  }
+    }
+  else
+    {
+      int send_stopped = 0;
+
+      /* If the selected thread is replaying, we do an implicit "record goto
+	 end" to make it stop replaying and indicate this to front-ends.  This
+	 causes the updated location to be printed for the selected thread.
+
+	 If it isn't replaying, we will send an unspecific stopped notification
+	 to front-ends at the end.  This doesn't print the (unchanged) location
+	 but indicates to front-ends that other thread's locations may have
+	 changed.  */
+      tp = inferior_thread ();
+      if (tp != NULL && btrace_is_replaying (tp))
+	record_btrace_set_replay (tp, NULL);
+      else
+	send_stopped = 1;
+
+      ALL_NON_EXITED_THREADS (tp)
+	if (tp->btrace.target != NULL)
+	  {
+	    /* Stop replaying before we disable tracing to clear TP's register
+	       state in addition to the btrace state.  */
+	    record_btrace_stop_replaying (tp);
+	    btrace_disable (tp);
+	  }
+
+      if (send_stopped)
+	observer_notify_normal_stop (NULL, 0);
+    }
 }
 
 /* The to_close method of target record-btrace.  */
diff --git a/gdb/testsuite/gdb.btrace/non-stop.c b/gdb/testsuite/gdb.btrace/non-stop.c
index c5870df..b4a7191 100644
--- a/gdb/testsuite/gdb.btrace/non-stop.c
+++ b/gdb/testsuite/gdb.btrace/non-stop.c
@@ -27,7 +27,9 @@ test (void *arg)
   i = 0; /* bp.1 */
   for (; i < 10; ++i) global += i; /* loop */
 
-  return arg; /* bp.2 */
+  global *= 2; /* bp.2 */
+
+  return arg; /* bp.3 */
 }
 
 int
@@ -41,5 +43,5 @@ main (void)
 
   pthread_join (th, NULL);
 
-  return 0; /* bp.3 */
+  return 0;
 }
diff --git a/gdb/testsuite/gdb.btrace/non-stop.exp b/gdb/testsuite/gdb.btrace/non-stop.exp
index 0d5cbe2..8dad07c 100644
--- a/gdb/testsuite/gdb.btrace/non-stop.exp
+++ b/gdb/testsuite/gdb.btrace/non-stop.exp
@@ -239,7 +239,22 @@ with_test_prefix "no progress" {
 }
 
 # now that both threads stopped replaying we may resume recording
-with_test_prefix "cont to end" {
+with_test_prefix "resume recording" {
     gdb_breakpoint $bp_3
-    gdb_cont_to_bp_line "$srcfile:$bp_3" all 1
+    gdb_cont_to_bp_line "$srcfile:$bp_3" all 2
+}
+
+# when we stop recording we get notifications for replaying threads
+with_test_prefix "stop" {
+    gdb_test "thread 1" ".*"
+    gdb_test "thread apply 2 record goto begin" ".*"
+
+    gdb_test "record stop" [multi_line \
+        "Thread 2 \[^\\\r\\\n\]* stopped replaying\." \
+        "\[^\\\r\\\n\]*$srcfile:$bp_3" \
+        "$bp_3\[^\\\r\\\n\]* bp\.3 \[^\\\r\\\n\]*" \
+        "Process record is stopped and all execution logs are deleted\." \
+    ]
+
+    gdb_test "info record" "No record target is currently active\."
 }
diff --git a/gdb/testsuite/gdb.btrace/stop.exp b/gdb/testsuite/gdb.btrace/stop.exp
new file mode 100644
index 0000000..074bab8
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/stop.exp
@@ -0,0 +1,70 @@
+# 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/>.
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+standard_testfile record_goto.c
+
+# start inferior
+if [prepare_for_testing $testfile.exp $testfile $srcfile] {
+	return -1
+}
+
+# we use the list command to check the current source location
+gdb_test "set listsize 1"
+
+if ![runto_main] {
+	return -1
+}
+
+# trace the call to the test function
+gdb_test_no_output "record btrace" "move: enable"
+gdb_test "next" ".*main\.3.*" "move: trace"
+
+# move to the beginning of the trace
+gdb_test "record goto begin" ".*main\.2.*" "move: navigate"
+
+# when we stop recording, we move back to the end of the trace
+gdb_test "record stop" "main\.3.*Process record is stopped.*" "move: stop"
+
+# check that we're really there
+gdb_test "list" ".*main\.3.*" "move: at end of trace"
+
+if ![runto_main] {
+	return -1
+}
+
+# trace the call to the test function
+gdb_test_no_output "record btrace" "already: enable"
+gdb_test "next" ".*main\.3.*" "already: trace"
+
+# we're already at the end so we didn't have to move
+gdb_test_multiple "record stop" "already: stop" {
+	-re "main.*$gdb_prompt $" {
+		fail "already: stop"
+	}
+	-re "Process record is stopped\[^\\\r\\\n\]*\r\n$gdb_prompt $" {
+		pass "already: stop"
+	}
+	-re "$gdb_prompt $" {
+		fail "already: stop"
+	}
+}
+
+# check that we're really there
+gdb_test "list" ".*main\.3.*" "already: at end of trace"
-- 
1.8.3.1

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

end of thread, other threads:[~2016-07-06 11:57 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-06 11:56 [PATCH 0/8] record: notify about "record goto" stop Markus Metzger
2016-07-06 11:56 ` [PATCH 2/8] record: do not allow record goto on a running thread Markus Metzger
2016-07-06 11:56 ` [PATCH 4/8] record: signal a record goto stop to front-ends Markus Metzger
2016-07-06 11:57 ` [PATCH 6/8] record-full: signal record-goto stop Markus Metzger
2016-07-06 11:57 ` [PATCH 1/8] btrace: check if we're replaying when setting the replay position to the end Markus Metzger
2016-07-06 11:57 ` [PATCH 8/8] btrace: record stop moves to the end of the trace Markus Metzger
2016-07-06 11:57 ` [PATCH 7/8] btrace-btrace: signal record-goto stop Markus Metzger
2016-07-06 11:57 ` [PATCH 3/8] infrun: export clear_proceed_status_thread Markus Metzger
2016-07-06 11:57 ` [PATCH 5/8] mi, testsuite: add another EXTRA option to mi_expect_stop Markus Metzger

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).