Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Switch out and in of tfind mode, when handling an event, in non-stop mode.
@ 2010-02-24  1:08 Pedro Alves
  2010-02-24  7:33 ` Stan Shebs
  2011-02-11 15:10 ` Pedro Alves
  0 siblings, 2 replies; 5+ messages in thread
From: Pedro Alves @ 2010-02-24  1:08 UTC (permalink / raw)
  To: gdb-patches

When debugging in non-stop mode, we can be inspecting the
trace buffer (so called tfind mode), while the live
target is running (as opposed to stopped, not as opposed to dead).
As such, threads can still hit breakpoints, signals,
etc., while in tfind mode.  At least internal breakpoints
(such as thread event or shared library event breakpoint)
should be resolved as quickly as possible, and transparently.
GDB is indeed still able to handle those, since in non-stop
mode the target reports stop events asynchronously to
infrun, but, whatever reads/writes of memory, registers, etc. need
to be done while handling the event up until the thread is
resumed, _must_ be done on the live target, not on the
trace buffer.  Since to tfind or not tfind mode is global
state (all the way through to the target side as well),
we need to swap out and in of such mode.  Hence, this patch
below.  I've applied it.

-- 
Pedro Alves

2010-02-24  Pedro Alves  <pedro@codesourcery.com>
	    Stan Shebs  <stan@codesourcery.com>

	gdb/
	* tracepoint.h (set_traceframe_number)
	(cleanup_restore_current_traceframe): Declare.
	* tracepoint.c (set_traceframe_number): New.
	(struct current_traceframe_cleanup): New.
	(do_restore_current_traceframe_cleanup)
	(restore_current_traceframe_cleanup_dtor)
	(make_cleanup_restore_current_traceframe): New.
	* infrun.c: Include tracepoint.h.
	(fetch_inferior_event): Switch out and in of tfind mode.

---
 gdb/infrun.c     |   11 +++++++++
 gdb/tracepoint.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/tracepoint.h |    3 ++
 3 files changed, 75 insertions(+)

Index: src/gdb/tracepoint.c
===================================================================
--- src.orig/gdb/tracepoint.c	2010-02-17 16:37:23.000000000 +0000
+++ src/gdb/tracepoint.c	2010-02-24 00:55:00.000000000 +0000
@@ -2538,6 +2538,67 @@ get_traceframe_number (void)
   return traceframe_number;
 }
 
+/* Make the traceframe NUM be the current trace frame.  Does nothing
+   if NUM is already current.  */
+
+void
+set_traceframe_number (int num)
+{
+  int newnum;
+
+  if (traceframe_number == num)
+    {
+      /* Nothing to do.  */
+      return;
+    }
+
+  newnum = target_trace_find (tfind_number, num, 0, 0, NULL);
+
+  if (newnum != num)
+    warning (_("could not change traceframe"));
+
+  traceframe_number = newnum;
+
+  /* Changing the traceframe changes our view of registers and of the
+     frame chain.  */
+  registers_changed ();
+}
+
+/* A cleanup used when switching away and back from tfind mode.  */
+
+struct current_traceframe_cleanup
+{
+  /* The traceframe we were inspecting.  */
+  int traceframe_number;
+};
+
+static void
+do_restore_current_traceframe_cleanup (void *arg)
+{
+  struct current_traceframe_cleanup *old = arg;
+
+  set_traceframe_number (old->traceframe_number);
+}
+
+static void
+restore_current_traceframe_cleanup_dtor (void *arg)
+{
+  struct current_traceframe_cleanup *old = arg;
+
+  xfree (old);
+}
+
+struct cleanup *
+make_cleanup_restore_current_traceframe (void)
+{
+  struct current_traceframe_cleanup *old;
+
+  old = xmalloc (sizeof (struct current_traceframe_cleanup));
+  old->traceframe_number = traceframe_number;
+
+  return make_cleanup_dtor (do_restore_current_traceframe_cleanup, old,
+			    restore_current_traceframe_cleanup_dtor);
+}
 
 /* Given a number and address, return an uploaded tracepoint with that
    number, creating if necessary.  */
Index: src/gdb/tracepoint.h
===================================================================
--- src.orig/gdb/tracepoint.h	2010-01-17 15:51:54.000000000 +0000
+++ src/gdb/tracepoint.h	2010-02-24 00:44:25.000000000 +0000
@@ -140,6 +140,9 @@ extern void (*deprecated_trace_find_hook
 extern void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
 
 int get_traceframe_number (void);
+void set_traceframe_number (int);
+struct cleanup *make_cleanup_restore_current_traceframe (void);
+
 void free_actions (struct breakpoint *);
 enum actionline_type validate_actionline (char **, struct breakpoint *);
 
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2010-02-17 01:22:10.000000000 +0000
+++ src/gdb/infrun.c	2010-02-24 00:55:37.000000000 +0000
@@ -51,6 +51,7 @@
 #include "record.h"
 #include "inline-frame.h"
 #include "jit.h"
+#include "tracepoint.h"
 
 /* Prototypes for local functions */
 
@@ -1761,6 +1762,16 @@ proceed (CORE_ADDR addr, enum target_sig
 			"infrun: proceed (addr=%s, signal=%d, step=%d)\n",
 			paddress (gdbarch, addr), siggnal, step);
 
+  /* We're handling a live event, so make sure we're doing live
+     debugging.  If we're looking at traceframes while the target is
+     running, we're going to need to get back to that mode after
+     handling the event.  */
+  if (non_stop)
+    {
+      make_cleanup_restore_current_traceframe ();
+      set_traceframe_number (-1);
+    }
+
   if (non_stop)
     /* In non-stop, each thread is handled individually.  The context
        must already be set to the right thread here.  */


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

end of thread, other threads:[~2011-02-11 15:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-24  1:08 Switch out and in of tfind mode, when handling an event, in non-stop mode Pedro Alves
2010-02-24  7:33 ` Stan Shebs
2010-02-24 15:59   ` Pedro Alves
2010-02-24 21:44     ` Pedro Alves
2011-02-11 15:10 ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox