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: Make linux-nat.c's non-stop mode target_stop implementation really asynchronous.


On Friday 09 September 2011 20:51:55, Pedro Alves wrote:
> This makes non-stop mode's "(gdb) interrupt", or rather the linux-nat.c's
> target_stop implementation truly asynchronous, like remote.c's counterpart,
> closer to gdbserver's linux-low.c implementation.
> 
> Currently, we 
> 
>  - queue a SIGSTOP
>  - wait for it to be reported
>  - leave a event pending
>  - tell the event loop there's something to handle
> 
> all from within linux_nat_stop_lwp (from interrupt -> target_stop).
> 
> Back to the event loop, we'd noticing a target event,
> and go do target_wait, collecting the pending event.
> 
> Now we'll just
> 
>  - queue a SIGSTOP and leave.  
> 
> Eventually, the lwp really stops, and we'll collect
> the stop as usual.  We do need to record in the lwp that
> we're stopping it, and that's what the new last_resume_kind
> field is for.

...

>        /* A pending SIGSTOP may interfere with the normal stream of
>           events.  In a typical case where interference is a problem,
> @@ -3747,7 +3781,10 @@ retry:
>        iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
>      }
>    else
> -    lp->resumed = 0;
> +    {
> +      lp->resumed = 0;
> +      lp->last_resume_kind = resume_stop;
> +    }
>  
>    if (linux_nat_status_is_event (status))
>      {
> @@ -3770,6 +3807,16 @@ retry:
>  
>    restore_child_signals_mask (&prev_mask);
>  
> +  if (lp->last_resume_kind == resume_stop

Whoops, obvious blunder here.  We're always clearing
lp->last_resume_kind to resume_stop just a bit above,
so this will always be true.  The patch below
corrects this.  I've applied it.

> +      && ourstatus->kind == TARGET_WAITKIND_STOPPED
> +      && WSTOPSIG (status) == SIGSTOP)



2011-10-10  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* linux-nat.c (linux_nat_wait_1): Copy the event lwp's
	last_resume_kind before clearing it, and use the copy instead to
	determine whether to report a SIGSTOP as TARGET_SIGNAL_0.  Use
	resume_clear_callback in the non-stop path too.

---
 gdb/linux-nat.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2011-10-10 14:19:22.087660163 +0100
+++ src/gdb/linux-nat.c	2011-10-10 14:20:00.527660156 +0100
@@ -3335,6 +3335,7 @@ linux_nat_wait_1 (struct target_ops *ops
 		  int target_options)
 {
   static sigset_t prev_mask;
+  enum resume_kind last_resume_kind;
   struct lwp_info *lp = NULL;
   int options = 0;
   int status = 0;
@@ -3747,14 +3748,20 @@ retry:
 	 why.  */
       iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
 
+      /* We'll need this to determine whether to report a SIGSTOP as
+	 TARGET_WAITKIND_0.  Need to take a copy because
+	 resume_clear_callback clears it.  */
+      last_resume_kind = lp->last_resume_kind;
+
       /* In all-stop, from the core's perspective, all LWPs are now
 	 stopped until a new resume action is sent over.  */
       iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
     }
   else
     {
-      lp->resumed = 0;
-      lp->last_resume_kind = resume_stop;
+      /* See above.  */
+      last_resume_kind = lp->last_resume_kind;
+      resume_clear_callback (lp, NULL);
     }
 
   if (linux_nat_status_is_event (status))
@@ -3778,7 +3785,7 @@ retry:
 
   restore_child_signals_mask (&prev_mask);
 
-  if (lp->last_resume_kind == resume_stop
+  if (last_resume_kind == resume_stop
       && ourstatus->kind == TARGET_WAITKIND_STOPPED
       && WSTOPSIG (status) == SIGSTOP)
     {


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