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] 04/10 per-thread commands in non-stop mode


A Tuesday 06 May 2008 16:48:38, Pedro Alves wrote:
> This patch deprecates the previous patches posted in this thread:
>  [RFA] Make continuations per-thread.
>  http://sourceware.org/ml/gdb-patches/2008-04/
>
> Given that,
>
> Âall-stop mode:
> Â - There can only be one exec command active at any time.
>
> Ânon-stop mode:
> Â - There can be more than one exec command active at any time.
> Â - Any given thread can only have one command active at any time.
>
> A continuation is a mechanism to finish a command. ÂIn all-stop
> mode, when the inferior stops and GDB finishes handling that
> event, we give the user the control again. ÂThe previous command
> is finished at this point. ÂIt is up to the user to decide
> what to do next. ÂSince we only allow one exec command at any
> given time, the next exec command the user issues fully
> replaces the previous one.
>
> In non-stop, we can have more than one exec command active, but
> only one per thread. ÂSince continuations are a mechanism of
> finishing a command, that is, they implement 3) below:
>
> Â1) prepare inferior (insert internal breakpoints, etc.)
> Â2) resume inferior and wait for stop
> Â3) finish off the command (remove internal breakpoints, etc.)
>
> ... and we can have a command per thread, it makes sense to
> make each thread have a continuation.
>
> Now, some commands carry "command state" with them. ÂThe biggest
> example is the "step"-like commands: Âstep/stepi/next. ÂWhen
> we have per-thread commands, we also need to store
> individual step-like command state per thread.
>
> So, in non-stop, we context switch all of these:
>
> Âenum step_over_calls_kind step_over_calls;
> Âint stop_step;
> Âint step_multi;
> Âenum target_signal stop_signal;
> Âint step_current_line;
> Âstruct symtab *step_current_symtab;
> Âstruct symbol *step_start_function;
>
> ... which define the state of a stepping command.
>
> So,
>  In all-stop, there's one allowed global command (and its continuations).
>  In non-stop, there can be one command per thread (and their
> continuations).
>

As said, after posting I realized that I also need to
context-switch stop_bpstat due to continue_command relying on it.

 [remove global stop_bpstat dependency from breakpoints module]
 http://sourceware.org/ml/gdb-patches/2008-05/msg00266.html

In non-stop the use of any_running in top.c is too restrictive,
so in non-stop mode, that is adapted to check the current thread, while
leaving the check for all threads in all-stop.

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

	* gdbthread.h: Remove unneeded forward declarations.
	Include "inferior.h".
	(struct thread_info): Add continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi and stop_signal members.
	(save_infrun_state): Add continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi and stop_signal parameters.
	(load_infrun_state): Add continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi and stop_signal parameters.

	* thread.c (load_infrun_state): In non-stop mode, load
	continuations, intermediate_continuations, proceed_to_finish,
	step_over_calls, stop_step, step_multi and stop_signal.
	(save_infrun_state): Store continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi, stop_signal and stop_bpstat.
	(save_infrun_state): Store continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi, stop_signal and stop_bpstat.

	* infrun.c (context_switch): Context switch continuations,
	intermediate_continuations, proceed_to_finish, step_over_calls,
	stop_step, step_multi, stop_signal and stop_bpstat.

	* Makefile.in (gdbthread_h): Depend on $(inferior_h).

---
 gdb/Makefile.in |    2 +-
 gdb/gdbthread.h |   43 ++++++++++++++++++++++++++++++++++---------
 gdb/infrun.c    |   18 ++++++++++++++++--
 gdb/thread.c    |   48 ++++++++++++++++++++++++++++++++++++++++++++++--
 gdb/top.c       |   10 ++++++----
 5 files changed, 103 insertions(+), 18 deletions(-)

Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h	2008-05-19 12:38:09.000000000 +0100
+++ src/gdb/gdbthread.h	2008-05-19 12:38:26.000000000 +0100
@@ -22,17 +22,12 @@
 #ifndef GDBTHREAD_H
 #define GDBTHREAD_H
 
-struct breakpoint;
-struct frame_id;
 struct symtab;
 
-/* For bpstat */
 #include "breakpoint.h"
-
-/* For struct frame_id.  */
 #include "frame.h"
-
 #include "ui-out.h"
+#include "inferior.h"
 
 struct thread_info
 {
@@ -82,6 +77,20 @@ struct thread_info
      when we finally do stop stepping.  */
   bpstat stepping_through_solib_catchpoints;
 
+  /* The below are only per-thread in non-stop mode.  */
+  /* Per-thread command support.  */
+  struct continuation *continuations;
+  struct continuation *intermediate_continuations;
+  int proceed_to_finish;
+  enum step_over_calls_kind step_over_calls;
+  int stop_step;
+  int step_multi;
+
+  enum target_signal stop_signal;
+  /* Used in continue_command to set the proceed count of the
+     breakpoint the thread stopped at.  */
+  bpstat stop_bpstat;
+
   /* Private data used by the target vector implementation.  */
   struct private_thread_info *private;
 };
@@ -145,7 +154,15 @@ extern void save_infrun_state (ptid_t pt
 			       int       stepping_through_solib_after_catch,
 			       bpstat    stepping_through_solib_catchpoints,
 			       int       current_line,
-			       struct symtab *current_symtab);
+			       struct symtab *current_symtab,
+			       struct continuation *continuations,
+			       struct continuation *intermediate_continuations,
+			       int proceed_to_finish,
+			       enum step_over_calls_kind step_over_calls,
+			       int stop_step,
+			       int step_multi,
+			       enum target_signal stop_signal,
+			       bpstat stop_bpstat);
 
 /* infrun context switch: load the debugger state previously saved
    for the given thread.  */
@@ -157,10 +174,18 @@ extern void load_infrun_state (ptid_t pt
 			       CORE_ADDR *step_range_end,
 			       struct frame_id *step_frame_id,
 			       int       *another_trap,
-			       int       *stepping_through_solib_affter_catch,
+			       int       *stepping_through_solib_after_catch,
 			       bpstat    *stepping_through_solib_catchpoints,
 			       int       *current_line,
-			       struct symtab **current_symtab);
+			       struct symtab **current_symtab,
+			       struct continuation **continuations,
+			       struct continuation **intermediate_continuations,
+			       int *proceed_to_finish,
+			       enum step_over_calls_kind *step_over_calls,
+			       int *stop_step,
+			       int *step_multi,
+			       enum target_signal *stop_signal,
+			       bpstat *stop_bpstat);
 
 /* Switch from one thread to another.  */
 extern void switch_to_thread (ptid_t ptid);
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c	2008-05-19 12:38:09.000000000 +0100
+++ src/gdb/thread.c	2008-05-19 12:38:26.000000000 +0100
@@ -329,7 +329,15 @@ load_infrun_state (ptid_t ptid,
 		   int *stepping_through_solib_after_catch,
 		   bpstat *stepping_through_solib_catchpoints,
 		   int *current_line,
-		   struct symtab **current_symtab)
+		   struct symtab **current_symtab,
+		   struct continuation **continuations,
+		   struct continuation **intermediate_continuations,
+		   int *proceed_to_finish,
+		   enum step_over_calls_kind *step_over_calls,
+		   int *stop_step,
+		   int *step_multi,
+		   enum target_signal *stop_signal,
+		   bpstat *stop_bpstat)
 {
   struct thread_info *tp;
 
@@ -352,6 +360,20 @@ load_infrun_state (ptid_t ptid,
     tp->stepping_through_solib_catchpoints;
   *current_line = tp->current_line;
   *current_symtab = tp->current_symtab;
+
+  /* In all-stop mode, these are global state, while in non-stop mode,
+     they are per thread.  */
+  if (non_stop)
+    {
+      *continuations = tp->continuations;
+      *intermediate_continuations = tp->intermediate_continuations;
+      *proceed_to_finish = tp->proceed_to_finish;
+      *step_over_calls = tp->step_over_calls;
+      *stop_step = tp->stop_step;
+      *step_multi = tp->step_multi;
+      *stop_signal = tp->stop_signal;
+      *stop_bpstat = tp->stop_bpstat;
+    }
 }
 
 /* Save infrun state for the thread PID.  */
@@ -368,7 +390,15 @@ save_infrun_state (ptid_t ptid,
 		   int stepping_through_solib_after_catch,
 		   bpstat stepping_through_solib_catchpoints,
 		   int current_line,
-		   struct symtab *current_symtab)
+		   struct symtab *current_symtab,
+		   struct continuation *continuations,
+		   struct continuation *intermediate_continuations,
+		   int proceed_to_finish,
+		   enum step_over_calls_kind step_over_calls,
+		   int stop_step,
+		   int step_multi,
+		   enum target_signal stop_signal,
+		   bpstat stop_bpstat)
 {
   struct thread_info *tp;
 
@@ -389,6 +419,20 @@ save_infrun_state (ptid_t ptid,
   tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
   tp->current_line = current_line;
   tp->current_symtab = current_symtab;
+
+  /* In all-stop mode, these are global state, while in non-stop mode,
+     they are per thread.  */
+  if (non_stop)
+    {
+      tp->continuations = continuations;
+      tp->intermediate_continuations = intermediate_continuations;
+      tp->proceed_to_finish = proceed_to_finish;
+      tp->step_over_calls = step_over_calls;
+      tp->stop_step = stop_step;
+      tp->step_multi = step_multi;
+      tp->stop_signal = stop_signal;
+      tp->stop_bpstat = stop_bpstat;
+    }
 }
 
 /* Return true if TP is an active thread. */
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-05-19 12:38:24.000000000 +0100
+++ src/gdb/infrun.c	2008-05-19 12:38:26.000000000 +0100
@@ -1605,7 +1605,14 @@ context_switch (struct execution_control
 			 ecs->stepping_over_breakpoint,
 			 ecs->stepping_through_solib_after_catch,
 			 ecs->stepping_through_solib_catchpoints,
-			 ecs->current_line, ecs->current_symtab);
+			 ecs->current_line, ecs->current_symtab,
+			 cmd_continuation, intermediate_continuation,
+			 proceed_to_finish,
+			 step_over_calls,
+			 stop_step,
+			 step_multi,
+			 stop_signal,
+			 stop_bpstat);
 
       /* Load infrun state for the new thread.  */
       load_infrun_state (ecs->ptid, &prev_pc,
@@ -1615,7 +1622,14 @@ context_switch (struct execution_control
 			 &ecs->stepping_over_breakpoint,
 			 &ecs->stepping_through_solib_after_catch,
 			 &ecs->stepping_through_solib_catchpoints,
-			 &ecs->current_line, &ecs->current_symtab);
+			 &ecs->current_line, &ecs->current_symtab,
+			 &cmd_continuation, &intermediate_continuation,
+			 &proceed_to_finish,
+			 &step_over_calls,
+			 &stop_step,
+			 &step_multi,
+			 &stop_signal,
+			 &stop_bpstat);
     }
 
   switch_to_thread (ecs->ptid);
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in	2008-05-19 12:38:09.000000000 +0100
+++ src/gdb/Makefile.in	2008-05-19 12:38:26.000000000 +0100
@@ -801,7 +801,7 @@ gdb_stabs_h = gdb-stabs.h
 gdb_stat_h = gdb_stat.h
 gdb_string_h = gdb_string.h
 gdb_thread_db_h = gdb_thread_db.h
-gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h) $(ui_out_h)
+gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h) $(ui_out_h) $(inferior_h)
 gdbtypes_h = gdbtypes.h $(hashtab_h)
 gdb_vfork_h = gdb_vfork.h
 gdb_wait_h = gdb_wait.h
Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2008-05-19 12:38:31.000000000 +0100
+++ src/gdb/top.c	2008-05-19 12:41:05.000000000 +0100
@@ -417,10 +417,12 @@ execute_command (char *p, int from_tty)
 
       /* If the target is running, we allow only a limited set of
          commands. */
-      if (target_can_async_p ()
-	  && any_running ()
-	  && !get_cmd_async_ok (c))
-	error (_("Cannot execute this command while the target is running."));
+      if (target_can_async_p () && !get_cmd_async_ok (c))
+	{
+	  if ((!non_stop && any_running ())
+	      || (non_stop && is_running (inferior_ptid)))
+	    error (_("Cannot execute this command while the target is running."));
+	}
 
       /* Pass null arg rather than an empty one.  */
       arg = *p ? p : 0;

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