This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] 07/10 non-stop inferior control


A Tuesday 06 May 2008 16:49:23, Pedro Alves wrote:
> This patch adds the inferior control support for non-stop mode.
>
> In non-stop mode, each thread is handled individually.  It should
> be like you have a separate debugger attached to each thread.
> To accomplish that, as soon as we have an event, we context switch
> to it, and go on handling it.  The cases of hiting a breakpoint
> in another thread while we're stepping don't need to be handled
> specially, as the stepping thread will have its state, and the
> other thread will have its own state.
>
> Every exec command should apply only to the selected thread.
>
> A new target_stop_ptid method was added to request the target
> to interrupt a single thread.
>
> Several checks have been added so GDB doesn't try to do
> things with running threads, which don't make sense,
> like asking for the current PC of a running thread.
>
> Info threads now shows the running state of a thread.  MI
> support can be added on top.
>
> (gdb) info threads
> Â 3 Thread 0xf7603b90 (LWP 23454) Â(running)
> * 2 Thread 0xf7e04b90 (LWP 23453) Â0xffffe410 in __kernel_vsyscall ()
> Â 1 Thread 0xf7e056b0 (LWP 23450) Â(running)

Updated patch, mostly for convenience.  The only thing that changed worth
of notice, was a check for non_stop in prepare_to_proceed
moved to its caller instead.

-- 
Pedro Alves
2008-05-19  Pedro Alves  <pedro@codesourcery.com>

	* infrun.c (resume): In non-stop mode, always resume just one
	thread.
	(proceed): Don't call prepare_to_proceed in non-stop mode.
	(fetch_inferior_event): In non-stop mode, switch context before
	handling the event.
	(error_is_running, ensure_not_running): New.
	(handle_inferior_event): In non-stop mode: Mark only the event
	thread as stopped. Require that the target module handles new
	threads correctly.  Don't switch to infwait_thread_hop_state.
	(normal_stop): Only mark not-running if inferior hasn't exited.
	In non-stop mode, only mark the event thread.

	* thread.c (print_thread_info): Don't read from a running thread.
	Output "(running)" if thread is running.
	(switch_to_thread): Don't read stop_pc if thread is running.
	(do_restore_current_thread_cleanup): Don't write to a running
	thread.
	(thread_apply_all_command): Don't read from a running thread.  In
	non-stop mode, do a full context-switch instead of just switching
	threads.
	(thread_apply_command): In non-stop mode, do a full context-switch
	instead of just switching threads.
	(do_captured_thread_select): Likewise.  Inform user if selected
	thread is running.

	* inf-loop.c (inferior_event_handler): In non-stop mode, don't
	unregister the target from the event loop.
	
	* infcmd.c (continue_command, step_1, jump_command)
	(signal_command): Ensure the selected thread isn't running.
	(interrupt_target_command): In non-stop mode, either interrupt
	only the selected thread, or read the thread id to interrupt from
	a parameter.

	* inferior.h (error_is_running, ensure_not_running): Declare.

	* target.h (struct target_ops): Add to_stop_ptid member.
	(target_stop_ptid): Define.
	* target.c (update_current_target): Inherit to_stop_ptid.  Default
	to_stop_ptid to target_ignore.
	(debug_to_stop_ptid): New.
	(debug_to_rcmd): Set to_stop_ptid.

---
 gdb/inf-loop.c |   14 ++++--
 gdb/infcmd.c   |   25 +++++++++++
 gdb/inferior.h |    6 ++
 gdb/infrun.c   |  121 +++++++++++++++++++++++++++++++++++++++++++--------------
 gdb/target.c   |   13 ++++++
 gdb/target.h   |    7 +++
 gdb/thread.c   |  100 +++++++++++++++++++++++++++++++++--------------
 7 files changed, 223 insertions(+), 63 deletions(-)

Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-05-19 12:41:37.000000000 +0100
+++ src/gdb/infrun.c	2008-05-19 12:41:43.000000000 +0100
@@ -1052,9 +1052,15 @@ a command like `return' or `jump' to con
 	  resume_ptid = inferior_ptid;
 	}
 
-      if ((scheduler_mode == schedlock_on)
-	  || (scheduler_mode == schedlock_step
-	      && (step || singlestep_breakpoints_inserted_p)))
+      if (non_stop)
+	{
+	  /* With non-stop mode on, threads are always handled
+	     individually.  */
+	  resume_ptid = inferior_ptid;
+	}
+      else if ((scheduler_mode == schedlock_on)
+	       || (scheduler_mode == schedlock_step
+		   && (step || singlestep_breakpoints_inserted_p)))
 	{
 	  /* User-settable 'scheduler' mode requires solo thread resume. */
 	  resume_ptid = inferior_ptid;
@@ -1215,19 +1221,27 @@ proceed (CORE_ADDR addr, enum target_sig
 			"infrun: proceed (addr=0x%s, signal=%d, step=%d)\n",
 			paddr_nz (addr), siggnal, step);
 
-  /* In a multi-threaded task we may select another thread
-     and then continue or step.
+  if (non_stop)
+    /* In non-stop, each thread is handled individually.  The context
+       must already be set to the right thread here.  */
+    ;
+  else
+    {
+      /* In a multi-threaded task we may select another thread and
+	 then continue or step.
 
-     But if the old thread was stopped at a breakpoint, it
-     will immediately cause another breakpoint stop without
-     any execution (i.e. it will report a breakpoint hit
-     incorrectly).  So we must step over it first.
-
-     prepare_to_proceed checks the current thread against the thread
-     that reported the most recent event.  If a step-over is required
-     it returns TRUE and sets the current thread to the old thread. */
-  if (prepare_to_proceed (step))
-    oneproc = 1;
+	 But if the old thread was stopped at a breakpoint, it will
+	 immediately cause another breakpoint stop without any
+	 execution (i.e. it will report a breakpoint hit incorrectly).
+	 So we must step over it first.
+
+	 prepare_to_proceed checks the current thread against the
+	 thread that reported the most recent event.  If a step-over
+	 is required it returns TRUE and sets the current thread to
+	 the old thread. */
+      if (prepare_to_proceed (step))
+	oneproc = 1;
+    }
 
   if (oneproc)
     {
@@ -1529,6 +1543,15 @@ fetch_inferior_event (void *client_data)
   else
     ecs->ptid = target_wait (waiton_ptid, &ecs->ws);
 
+  if (non_stop
+      && ecs->ws.kind != TARGET_WAITKIND_IGNORE
+      && ecs->ws.kind != TARGET_WAITKIND_EXITED
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+    /* In non-stop mode, each thread is handled individually.  Switch
+       early, so the global state is set correctly for this
+       thread.  */
+    context_switch (ecs->ptid);
+
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (ecs);
 
@@ -1739,6 +1762,20 @@ init_infwait_state (void)
   infwait_state = infwait_normal_state;
 }
 
+void
+error_is_running (void)
+{
+  error (_("\
+Cannot execute this command while the selected thread is running."));
+}
+
+void
+ensure_not_running (void)
+{
+  if (is_running (inferior_ptid))
+    error_is_running ();
+}
+
 /* Given an execution control state that has been freshly filled in
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
@@ -1810,11 +1847,15 @@ handle_inferior_event (struct execution_
       && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
     add_thread (ecs->ptid);
 
-  /* Mark all threads as not-executing.  In non-stop, this should be
-     adjusted to only mark ecs->ptid.  */
   if (ecs->ws.kind != TARGET_WAITKIND_IGNORE
       && stop_soon != STOP_QUIETLY)
-    set_executing (pid_to_ptid (-1), 0);
+    {
+      /* Mark the stopped threads accordingly.  */
+      if (!non_stop)
+	set_executing (pid_to_ptid (-1), 0);
+      else
+	set_executing (ecs->ptid, 0);
+    }
 
   switch (ecs->ws.kind)
     {
@@ -2052,15 +2093,22 @@ handle_inferior_event (struct execution_
       return;
     }
 
-  /* We may want to consider not doing a resume here in order to give
-     the user a chance to play with the new thread.  It might be good
-     to make that a user-settable option.  */
-
-  /* At this point, all threads are stopped (happens automatically in
-     either the OS or the native code).  Therefore we need to continue
-     all threads in order to make progress.  */
   if (ecs->new_thread_event)
     {
+      if (non_stop)
+	/* Non-stop assumes that the target handles adding new threads
+	   to the thread list.  */
+	internal_error (__FILE__, __LINE__,
+			"target misreported a new thread in non-stop mode.");
+
+      /* We may want to consider not doing a resume here in order to
+	 give the user a chance to play with the new thread.  It might
+	 be good to make that a user-settable option.  */
+
+      /* At this point, all threads are stopped (happens automatically
+	 in either the OS or the native code).  Therefore we need to
+	 continue all threads in order to make progress.  */
+
       target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
@@ -2127,6 +2175,9 @@ handle_inferior_event (struct execution_
 
   if (!ptid_equal (deferred_step_ptid, null_ptid))
     {
+      /* In non-stop mode, there's never a deferred_step_ptid set.  */
+      gdb_assert (!non_stop);
+
       /* If we stopped for some other reason than single-stepping, ignore
 	 the fact that we were supposed to switch back.  */
       if (stop_signal == TARGET_SIGNAL_TRAP)
@@ -2275,8 +2326,13 @@ handle_inferior_event (struct execution_
 	      if (!ptid_equal (inferior_ptid, ecs->ptid))
 		context_switch (ecs->ptid);
 
-	      waiton_ptid = ecs->ptid;
-	      infwait_state = infwait_thread_hop_state;
+	      if (!non_stop)
+		{
+		  /* Only need to require the next event from this
+		     thread in all-stop mode.  */
+		  waiton_ptid = ecs->ptid;
+		  infwait_state = infwait_thread_hop_state;
+		}
 
 	      tss->stepping_over_breakpoint = 1;
 	      keep_going (ecs);
@@ -3830,7 +3886,16 @@ done:
   /* Delete the breakpoint we stopped at, if it wants to be deleted.
      Delete any breakpoint that is to be deleted at the next stop.  */
   breakpoint_auto_delete (stop_bpstat);
-  set_running (pid_to_ptid (-1), 0);
+
+  if (target_has_execution
+      && last.kind != TARGET_WAITKIND_SIGNALLED
+      && last.kind != TARGET_WAITKIND_EXITED)
+    {
+      if (!non_stop)
+	set_running (pid_to_ptid (-1), 0);
+      else
+	set_running (inferior_ptid, 0);
+    }
 }
 
 static int
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c	2008-05-19 12:38:26.000000000 +0100
+++ src/gdb/thread.c	2008-05-19 13:32:12.000000000 +0100
@@ -597,9 +597,12 @@ print_thread_info (struct ui_out *uiout,
   int current_thread = -1;
 
   /* Backup current thread and selected frame.  */
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
-  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
 
+  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
   make_cleanup_ui_out_list_begin_end (uiout, "threads");
 
   prune_threads ();
@@ -626,20 +629,26 @@ print_thread_info (struct ui_out *uiout,
       ui_out_text (uiout, " ");
       ui_out_field_string (uiout, "target-id", target_tid_to_str (tp->ptid));
 
-      extra_info = target_extra_thread_info (tp);
-      if (extra_info)
+      if (tp->running_)
+	ui_out_text (uiout, "  (running)\n");
+      else
 	{
-	  ui_out_text (uiout, " (");
-	  ui_out_field_string (uiout, "details", extra_info);
-	  ui_out_text (uiout, ")");
+	  extra_info = target_extra_thread_info (tp);
+	  if (extra_info)
+	    {
+	      ui_out_text (uiout, " (");
+	      ui_out_field_string (uiout, "details", extra_info);
+	      ui_out_text (uiout, ")");
+	    }
+	  ui_out_text (uiout, "  ");
+	  /* The switch below puts us at the top of the stack (leaf
+	     frame).  */
+	  switch_to_thread (tp->ptid);
+	  print_stack_frame (get_selected_frame (NULL),
+			     /* For MI output, print frame level.  */
+			     ui_out_is_mi_like_p (uiout),
+			     LOCATION);
 	}
-      ui_out_text (uiout, "  ");
-      /* That switch put us at the top of the stack (leaf frame).  */
-      switch_to_thread (tp->ptid);
-      print_stack_frame (get_selected_frame (NULL), 
-			 /* For MI output, print frame level.  */
-			 ui_out_is_mi_like_p (uiout),
-			 LOCATION);
 
       do_cleanups (chain2);
     }
@@ -655,6 +664,9 @@ print_thread_info (struct ui_out *uiout,
 	ui_out_field_int (uiout, "current-thread-id", current_thread);
     }
 
+  if (is_running (inferior_ptid))
+    return;
+
   /*  If case we were not able to find the original frame, print the
       new selected frame.  */
   if (frame_find_by_id (saved_frame_id) == NULL)
@@ -693,7 +705,11 @@ switch_to_thread (ptid_t ptid)
   inferior_ptid = ptid;
   reinit_frame_cache ();
   registers_changed ();
-  stop_pc = read_pc ();
+
+  if (!is_executing (ptid))
+    stop_pc = read_pc ();
+  else
+    stop_pc = ~(CORE_ADDR) 0;
 }
 
 static void
@@ -723,6 +739,7 @@ struct current_thread_cleanup
 {
   ptid_t inferior_ptid;
   struct frame_id selected_frame_id;
+  int was_running;
 };
 
 static void
@@ -730,7 +747,12 @@ do_restore_current_thread_cleanup (void 
 {
   struct current_thread_cleanup *old = arg;
   restore_current_thread (old->inferior_ptid);
-  restore_selected_frame (old->selected_frame_id);
+
+  /* A command like 'thread apply all $exec_command&' may change the
+     running state of the originally selected thread, so we have to
+     recheck it here.  */
+  if (!old->was_running && !is_running (old->inferior_ptid))
+    restore_selected_frame (old->selected_frame_id);
   xfree (old);
 }
 
@@ -742,6 +764,7 @@ make_cleanup_restore_current_thread (pti
     = xmalloc (sizeof (struct current_thread_cleanup));
   old->inferior_ptid = inferior_ptid;
   old->selected_frame_id = a_frame_id;
+  old->was_running = is_running (inferior_ptid);
   return make_cleanup (do_restore_current_thread_cleanup, old);
 }
 
@@ -758,8 +781,7 @@ static void
 thread_apply_all_command (char *cmd, int from_tty)
 {
   struct thread_info *tp;
-  struct cleanup *old_chain;
-  struct cleanup *saved_cmd_cleanup_chain;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
   char *saved_cmd;
   struct frame_id saved_frame_id;
   ptid_t current_ptid;
@@ -769,8 +791,12 @@ thread_apply_all_command (char *cmd, int
     error (_("Please specify a command following the thread ID list"));
   
   current_ptid = inferior_ptid;
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
-  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
+  make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
 
   /* It is safe to update the thread list now, before
      traversing it for "thread apply all".  MVS */
@@ -779,11 +805,15 @@ thread_apply_all_command (char *cmd, int
   /* Save a copy of the command in case it is clobbered by
      execute_command */
   saved_cmd = xstrdup (cmd);
-  saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
+  make_cleanup (xfree, saved_cmd);
   for (tp = thread_list; tp; tp = tp->next)
     if (thread_alive (tp))
       {
-	switch_to_thread (tp->ptid);
+	if (non_stop)
+	  context_switch_to (tp->ptid);
+	else
+	  switch_to_thread (tp->ptid);
+
 	printf_filtered (_("\nThread %d (%s):\n"),
 			 tp->num, target_tid_to_str (inferior_ptid));
 	execute_command (cmd, from_tty);
@@ -793,12 +823,10 @@ thread_apply_all_command (char *cmd, int
   if (!ptid_equal (current_ptid, inferior_ptid))
     thread_has_changed = 1;
 
-  do_cleanups (saved_cmd_cleanup_chain);
   do_cleanups (old_chain);
   /* Print stack frame only if we changed thread.  */
-  if (thread_has_changed)
+  if (thread_has_changed && !is_running (inferior_ptid))
     print_stack_frame (get_current_frame (), 1, SRC_LINE);
-
 }
 
 static void
@@ -822,7 +850,11 @@ thread_apply_command (char *tidlist, int
     error (_("Please specify a command following the thread ID list"));
 
   current_ptid = inferior_ptid;
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
+
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
   old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
 
   /* Save a copy of the command in case it is clobbered by
@@ -866,7 +898,10 @@ thread_apply_command (char *tidlist, int
 	    warning (_("Thread %d has terminated."), start);
 	  else
 	    {
-	      switch_to_thread (tp->ptid);
+	      if (non_stop)
+		context_switch_to (tp->ptid);
+	      else
+		switch_to_thread (tp->ptid);
 	      printf_filtered (_("\nThread %d (%s):\n"), tp->num,
 			       target_tid_to_str (inferior_ptid));
 	      execute_command (cmd, from_tty);
@@ -933,7 +968,10 @@ do_captured_thread_select (struct ui_out
   if (!thread_alive (tp))
     error (_("Thread ID %d has terminated."), num);
 
-  switch_to_thread (tp->ptid);
+  if (non_stop)
+    context_switch_to (tp->ptid);
+  else
+    switch_to_thread (tp->ptid);
 
   ui_out_text (uiout, "[Switching to thread ");
   ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
@@ -941,7 +979,11 @@ do_captured_thread_select (struct ui_out
   ui_out_text (uiout, target_tid_to_str (inferior_ptid));
   ui_out_text (uiout, ")]");
 
-  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+  if (!tp->running_)
+    print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+  else
+    ui_out_text (uiout, " (running)\n");
+
   return GDB_RC_OK;
 }
 
Index: src/gdb/inf-loop.c
===================================================================
--- src.orig/gdb/inf-loop.c	2008-05-19 12:38:09.000000000 +0100
+++ src/gdb/inf-loop.c	2008-05-19 12:41:43.000000000 +0100
@@ -73,11 +73,15 @@ inferior_event_handler (enum inferior_ev
       break;
 
     case INF_EXEC_COMPLETE:
-      /* Unregister the inferior from the event loop. This is done so that
-	 when the inferior is not running we don't get distracted by
-	 spurious inferior output.  */
-      if (target_has_execution)
-	target_async (NULL, 0);
+
+      if (!non_stop)
+	{
+	  /* Unregister the inferior from the event loop. This is done
+	     so that when the inferior is not running we don't get
+	     distracted by spurious inferior output.  */
+	  if (target_has_execution)
+	    target_async (NULL, 0);
+	}
 
       /* The call to async_enable_stdin below resets 'sync_execution'.
 	 However, if sync_execution is 1 now, we also need to show the
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2008-05-19 12:38:08.000000000 +0100
+++ src/gdb/infcmd.c	2008-05-19 13:32:11.000000000 +0100
@@ -612,6 +612,7 @@ continue_command (char *proc_count_exp, 
 {
   int async_exec = 0;
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background. */
   if (proc_count_exp != NULL)
@@ -713,6 +714,7 @@ step_1 (int skip_subroutines, int single
   int thread = -1;
 
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   if (count_string)
     async_exec = strip_bg_char (&count_string);
@@ -935,6 +937,7 @@ jump_command (char *arg, int from_tty)
   int async_exec = 0;
 
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background. */
   if (arg != NULL)
@@ -1035,6 +1038,7 @@ signal_command (char *signum_exp, int fr
 
   dont_repeat ();		/* Too dangerous.  */
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
   if (signum_exp != NULL)
@@ -2103,7 +2107,26 @@ interrupt_target_command (char *args, in
   if (target_can_async_p ())
     {
       dont_repeat ();		/* Not for the faint of heart */
-      target_stop ();
+
+      if (non_stop)
+	{
+	  ptid_t ptid;
+	  if (args && *args)
+	    {
+	      int num = value_as_long (parse_and_eval (args));
+
+	      if (!valid_thread_id (num))
+		error (_("Thread ID %d not known."), num);
+
+	      ptid = thread_id_to_pid (num);
+	    }
+	  else
+	    ptid = inferior_ptid;
+
+	  target_stop_ptid (ptid);
+	}
+      else
+	target_stop ();
     }
 }
 
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h	2008-05-19 12:41:35.000000000 +0100
+++ src/gdb/inferior.h	2008-05-19 12:41:43.000000000 +0100
@@ -245,6 +245,12 @@ extern void get_last_target_status(ptid_
 
 extern void follow_inferior_reset_breakpoints (void);
 
+/* Throw an error indicating the current thread is running.  */
+extern void error_is_running (void);
+
+/* Calls error_is_running if the current thread is running.  */
+extern void ensure_not_running (void);
+
 /* From infcmd.c */
 
 extern void tty_command (char *, int);
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2008-05-19 12:38:19.000000000 +0100
+++ src/gdb/target.h	2008-05-19 13:31:41.000000000 +0100
@@ -397,6 +397,7 @@ struct target_ops
     char *(*to_pid_to_str) (ptid_t);
     char *(*to_extra_thread_info) (struct thread_info *);
     void (*to_stop) (void);
+    void (*to_stop_ptid) (ptid_t ptid);
     void (*to_rcmd) (char *command, struct ui_file *output);
     char *(*to_pid_to_exec_file) (int pid);
     void (*to_log_command) (const char *);
@@ -895,6 +896,12 @@ int target_follow_fork (int follow_child
 
 #define target_stop current_target.to_stop
 
+/* Same as target_stop, but apply to PTID.  Used in non-stop mode to
+   stop a single thread without affecting the running state of the
+   others.  */
+#define target_stop_ptid(ptid) \
+     (*current_target.to_stop_ptid) (ptid)
+
 /* Send the specified COMMAND to the target's monitor
    (shell,interpreter) for execution.  The result of the query is
    placed in OUTBUF.  */
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2008-05-19 12:38:09.000000000 +0100
+++ src/gdb/target.c	2008-05-19 12:41:43.000000000 +0100
@@ -456,6 +456,7 @@ update_current_target (void)
       INHERIT (to_pid_to_str, t);
       INHERIT (to_extra_thread_info, t);
       INHERIT (to_stop, t);
+      INHERIT (to_stop_ptid, t);
       /* Do not inherit to_xfer_partial.  */
       INHERIT (to_rcmd, t);
       INHERIT (to_pid_to_exec_file, t);
@@ -632,6 +633,9 @@ update_current_target (void)
   de_fault (to_stop,
 	    (void (*) (void))
 	    target_ignore);
+  de_fault (to_stop_ptid,
+	    (void (*) (ptid_t))
+	    target_ignore);
   current_target.to_xfer_partial = current_xfer_partial;
   de_fault (to_rcmd,
 	    (void (*) (char *, struct ui_file *))
@@ -2939,6 +2943,14 @@ debug_to_stop (void)
 }
 
 static void
+debug_to_stop_ptid (ptid_t ptid)
+{
+  debug_target.to_stop_ptid (ptid);
+
+  fprintf_unfiltered (gdb_stdlog, "target_stop_pid\n");
+}
+
+static void
 debug_to_rcmd (char *command,
 	       struct ui_file *outbuf)
 {
@@ -3012,6 +3024,7 @@ setup_target_debug (void)
   current_target.to_thread_alive = debug_to_thread_alive;
   current_target.to_find_new_threads = debug_to_find_new_threads;
   current_target.to_stop = debug_to_stop;
+  current_target.to_stop_ptid = debug_to_stop_ptid;
   current_target.to_rcmd = debug_to_rcmd;
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]