(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.
+2010-02-24  Pedro Alves  <pedro@codesourcery.com>
+           Stan Shebs  <stan@codesourcery.com>
+
+       * 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.
+
 2010-02-24  Pedro Alves  <pedro@codesourcery.com>
 
        * breakpoint.c (breakpoint_init_inferior): Also delete
 
 #include "record.h"
 #include "inline-frame.h"
 #include "jit.h"
+#include "tracepoint.h"
 
 /* Prototypes for local functions */
 
                        "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.  */
 
   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.  */
 
 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 *);