This is the mail archive of the gdb-patches@sources.redhat.com 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] PTRACE_ATTACH problem on new Linux kernels


Andrew Cagney writes:
 > > Andrew Cagney writes:
 > >  > Solution 0 is to discard the STOP in infrun.c as part of the stop
 > >  > analyzis.
 > >  > 
 > > 
 > > Yes, but I am not sure it won't break the other cases that share that
 > > stop analysis. The stop_soon_quietly variable is relied upon in other
 > > places, like the start_remote function, the startup_inferior function,
 > > the sharedlib machinery. That's why I thought the handling it in the
 > > attach command would be safer.
 > 
 > It certainly doesn't break anything, however, it also makes the long 
 > term problem harder.
 > 
 > >  > > A first solution could be that upon continuing, gdb never sends a
 > >  > > SIGSTOP through the ptrace call. I.e. the stop_signal in
 > >  > > ptrace(PTRACE_CONT, pid, stop_signal) could be changed to
 > >  > > TARGET_SIGNAL_0 if it is TARGET_SIGNAL_STOP (such a call is in
 > >  > > proceed(), and we already do some signal munging there).
 > >  > > 
 > >  > > Another solution is to throw away the TARGET_SIGNAL_STOP that is saved
 > >  > > in stop_signal when we do an attach. This would be in
 > >  > > attach_command(), in infcmd.c. This way it would not come into play at
 > >  > > all at the next continue.
 > >  > 
 > >  > This will make the desperatly needed objective of trying to eliminate
 > >  > the global stop_signal variable just that bit more difficult.
 > >  > 
 > >  > If the already nasty hacks in HP/PA and solib code is ignored, the
 > >  > only places stop_signal is modified is in infrun.c.
 > >  > 
 > > 
 > > Hmm true, sigh.
 > 
 > Think about the frames code where things got so complicated that no one 
 > was game to change it.
 > With the changes in place I'm now finding my self fighting a rear-guard 
 > action to stop the old hacks re-appearing.
 > 
 > >  > > Yet another solution is that we 'hide' the TARGET_SIGNAL_STOP in
 > >  > > child_resume(), in i386-linux-nat.c but this would not be applicable
 > >  > > to the other linux arches.
 > >  > 
 > >  > Or discard the signal in resume()?
 > >  > 
 > > 
 > > yes, proceed() already does something like that, but that would mean
 > > that we modify the signal before doing the continue, and not after we
 > > receive it.  There is a lot that can happen between issuing an
 > > 'attach' command, and a later 'continue'. Maybe we would be discarding
 > > a valid SIGSTOP to pass to the inferior.
 > > 
 > > I think the only option left is to change the handle_inferior_event
 > > stop analysis, which is scary...
 > 
 > Conceptually, the code is being used as:
 > 
 > - connect to target
 > - force the WFI state machine into a specific initial state (stop 
 > normally, stop_soon_quietly or, now, stop_soon_with_sigstop) (yes, ok, 
 > no one believes me when I say that WFI is a state machine :-)
 > - run the WFI state machine to analize the target's state
 > 
 > Can stop_soon_quietly be [ab]used / extended to in a more general way 
 > force WFI into other states?  Either by treating it as bit fields or as 
 > alternative states?  e.g.,
 > 
 > enum stop_soon { stop_soon_normally, stop_soon_quietly, 
 > stop_soon_suspended };
 > 
 > or struct stop_soon { int quietly; int suspended; }
 > 
 > or ...
 > 
 > Andrew
 > 
 > 

Kind of. I am testing the following:

2003-02-18  Elena Zannoni  <ezannoni@redhat.com>

	* infrun.c (stop_soon_quietly): Make it an enum, to better
	override the default behavior of handle_inferior_event.
	(clear_proceed_status): Update uses of stop_soon_quietly to
	reflect that it is now an enum.
	(start_remote): Ditto.
	(handle_inferior_event): Change logic a bit if stop_soon_quietly
	is set to handle the new kernel behavior for attach/sigstop.
	Update uses of stop_soon_quietly.
	* inferior.h (enum stop_kind): New enum.
	* infcmd.c (attach_command): Use STOP_QUIETLY_NO_SIGSTOP.
	Reset normal handle_inferior_event behavior, afterwards.
	* fork-child.c (startup_inferior): Update.
	* alpha-tdep.c (heuristic_proc_start): Update.
	* solib-svr4.c (svr4_solib_create_inferior_hook): Update.
	* solib-sunos.c (sunos_solib_create_inferior_hook): Update.
	* solib-osf.c (osf_solib_create_inferior_hook): Update.
	* solib-irix.c (irix_solib_create_inferior_hook): Update.
	* remote-vx.c (vx_create_inferior): Update.
	* mips-tdep.c (heuristic_proc_start): Update.


Index: alpha-tdep.c
===================================================================
RCS file: /cvs/uberbaum/gdb/alpha-tdep.c,v
retrieving revision 1.60
diff -u -p -r1.60 alpha-tdep.c
--- alpha-tdep.c	31 Jan 2003 18:28:25 -0000	1.60
+++ alpha-tdep.c	18 Feb 2003 20:24:34 -0000
@@ -564,7 +564,7 @@ heuristic_proc_start (CORE_ADDR pc)
 	   stop_soon_quietly, but with this test, at least we
 	   don't print out warnings for every child forked (eg, on
 	   decstation).  22apr93 rich@cygnus.com.  */
-	if (!stop_soon_quietly)
+	if (stop_soon_quietly == NO_STOP_QUIETLY)
 	  {
 	    static int blurb_printed = 0;
 
Index: fork-child.c
===================================================================
RCS file: /cvs/uberbaum/gdb/fork-child.c,v
retrieving revision 1.18
diff -u -p -r1.18 fork-child.c
--- fork-child.c	16 Nov 2002 19:23:52 -0000	1.18
+++ fork-child.c	18 Feb 2003 20:24:35 -0000
@@ -409,7 +409,8 @@ startup_inferior (int ntraps)
 #else
   while (1)
     {
-      stop_soon_quietly = 1;	/* Make wait_for_inferior be quiet */
+      /* Make wait_for_inferior be quiet */
+      stop_soon_quietly = STOP_QUIETLY;
       wait_for_inferior ();
       if (stop_signal != TARGET_SIGNAL_TRAP)
 	{
@@ -444,5 +445,5 @@ startup_inferior (int ntraps)
 	}
     }
 #endif /* STARTUP_INFERIOR */
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
 }

Index: infcmd.c
===================================================================
RCS file: /cvs/uberbaum/gdb/infcmd.c,v
retrieving revision 1.72
diff -u -p -r1.72 infcmd.c
--- infcmd.c	1 Feb 2003 17:28:40 -0000	1.72
+++ infcmd.c	18 Feb 2003 20:24:38 -0000
@@ -1913,8 +1913,13 @@ attach_command (char *args, int from_tty
   /* No traps are generated when attaching to inferior under Mach 3
      or GNU hurd.  */
 #ifndef ATTACH_NO_WAIT
-  stop_soon_quietly = 1;
+  /* Careful here. See comments in inferior.h.  Basically some OSes
+     don't ignore SIGSTOPs on continue requests anymore.  We need a
+     way for handle_inferior_event to reset the stop_signal variable
+     after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for.  */
+  stop_soon_quietly = STOP_QUIETLY_NO_SIGSTOP;
   wait_for_inferior ();
+  stop_soon_quietly = NO_STOP_QUIETLY;
 #endif
 
   /*
Index: inferior.h
===================================================================
RCS file: /cvs/uberbaum/gdb/inferior.h,v
retrieving revision 1.42
diff -u -p -r1.42 inferior.h
--- inferior.h	21 Jan 2003 19:43:47 -0000	1.42
+++ inferior.h	18 Feb 2003 20:24:38 -0000
@@ -392,12 +392,37 @@ extern enum step_over_calls_kind step_ov
 
 extern int step_multi;
 
-/* Nonzero means expecting a trap and caller will handle it themselves.
-   It is used after attach, due to attaching to a process;
-   when running in the shell before the child program has been exec'd;
-   and when running some kinds of remote stuff (FIXME?).  */
+/* Nonzero means expecting a trap and caller will handle it
+   themselves.  It is used when running in the shell before the child
+   program has been exec'd; and when running some kinds of remote
+   stuff (FIXME?).  */
 
-extern int stop_soon_quietly;
+/* It is also used after attach, due to attaching to a process. This
+   is a bit trickier.  When doing an attach, the kernel stops the
+   debuggee with a SIGSTOP.  On newer GNU/Linux kernels (>= 2.5.61)
+   the handling of SIGSTOP for a ptraced process has changed. Earlier
+   versions of the kernel would ignore these SIGSTOPs, while now
+   SIGSTOP is treated like any other signal, i.e. it is not muffled.
+   
+   If the gdb user does a 'continue' after the 'attach', gdb passes
+   the global variable stop_signal (which stores the signal from the
+   attach, SIGSTOP) to the ptrace(PTRACE_CONT,...)  call.  This is
+   problematic, because the kernel doesn't ignore such SIGSTOP
+   now. I.e. it is reported back to gdb, which in turn presents it
+   back to the user.
+ 
+   To avoid the problem, we use STOP_QUIETLY_NO_SIGSTOP, which allows
+   gdb to clear the value of stop_signal after the attach, so that it
+   is not passed back down to the kernel.  */
+
+enum stop_kind
+  {
+    NO_STOP_QUIETLY = 0,
+    STOP_QUIETLY,
+    STOP_QUIETLY_NO_SIGSTOP
+  };
+
+extern enum stop_kind stop_soon_quietly;
 
 /* Nonzero if proceed is being used for a "finish" command or a similar
    situation when stop_registers should be saved.  */
Index: infrun.c
===================================================================
RCS file: /cvs/uberbaum/gdb/infrun.c,v
retrieving revision 1.96
diff -u -p -r1.96 infrun.c
--- infrun.c	31 Jan 2003 15:22:57 -0000	1.96
+++ infrun.c	18 Feb 2003 20:24:42 -0000
@@ -306,7 +306,7 @@ int stop_after_trap;
    when running in the shell before the child program has been exec'd;
    and when running some kinds of remote stuff (FIXME?).  */
 
-int stop_soon_quietly;
+enum stop_kind stop_soon_quietly;
 
 /* Nonzero if proceed is being used for a "finish" command or a similar
    situation when stop_registers should be saved.  */
@@ -679,7 +679,7 @@ clear_proceed_status (void)
   step_frame_id = null_frame_id;
   step_over_calls = STEP_OVER_UNDEBUGGABLE;
   stop_after_trap = 0;
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
   proceed_to_finish = 0;
   breakpoint_proceeded = 1;	/* We're about to proceed... */
 
@@ -822,7 +822,7 @@ start_remote (void)
 {
   init_thread_list ();
   init_wait_for_inferior ();
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   trap_expected = 0;
 
   /* Always go on waiting for the target, regardless of the mode. */
@@ -1261,7 +1261,7 @@ handle_inferior_event (struct execution_
          might be the shell which has just loaded some objects,
          otherwise add the symbols for the newly loaded objects.  */
 #ifdef SOLIB_ADD
-      if (!stop_soon_quietly)
+      if (stop_soon_quietly == NO_STOP_QUIETLY)
 	{
 	  /* Remove breakpoints, SOLIB_ADD might adjust
 	     breakpoint addresses via breakpoint_re_set.  */
@@ -1760,7 +1760,9 @@ handle_inferior_event (struct execution_
   if (stop_signal == TARGET_SIGNAL_TRAP
       || (breakpoints_inserted &&
 	  (stop_signal == TARGET_SIGNAL_ILL
-	   || stop_signal == TARGET_SIGNAL_EMT)) || stop_soon_quietly)
+	   || stop_signal == TARGET_SIGNAL_EMT))
+      || stop_soon_quietly == STOP_QUIETLY
+      || stop_soon_quietly == STOP_QUIETLY_NO_SIGSTOP)
     {
       if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
 	{
@@ -1768,9 +1770,24 @@ handle_inferior_event (struct execution_
 	  stop_stepping (ecs);
 	  return;
 	}
-      if (stop_soon_quietly)
+
+      /* This is originated from start_remote(), start_inferior() and
+         shared libraries hook functions.  */
+      if (stop_soon_quietly == STOP_QUIETLY)
 	{
 	  stop_stepping (ecs);
+	  return;
+	}
+
+      /* This originates from attach_command().  We need to overwrite
+         the stop_signal here, because some kernels don't ignore a
+         SIGSTOP in a subsequent ptrace(PTRACE_SONT,SOGSTOP) call.
+         See more comments in inferior.h.  */
+      if (stop_soon_quietly == STOP_QUIETLY_NO_SIGSTOP)
+	{
+	  stop_stepping (ecs);
+	  if (stop_signal == TARGET_SIGNAL_STOP)
+	    stop_signal = TARGET_SIGNAL_0;
 	  return;
 	}
 
Index: mips-tdep.c
===================================================================
RCS file: /cvs/uberbaum/gdb/mips-tdep.c,v
retrieving revision 1.161
diff -u -p -r1.161 mips-tdep.c
--- mips-tdep.c	28 Jan 2003 16:31:11 -0000	1.161
+++ mips-tdep.c	18 Feb 2003 20:24:49 -0000
@@ -1789,7 +1789,7 @@ heuristic_proc_start (CORE_ADDR pc)
 	   stop_soon_quietly, but with this test, at least we
 	   don't print out warnings for every child forked (eg, on
 	   decstation).  22apr93 rich@cygnus.com.  */
-	if (!stop_soon_quietly)
+	if (stop_soon_quietly == NO_STOP_QUIETLY)
 	  {
 	    static int blurb_printed = 0;

Index: remote-vx.c
===================================================================
RCS file: /cvs/uberbaum/gdb/remote-vx.c,v
retrieving revision 1.23
diff -u -p -r1.23 remote-vx.c
--- remote-vx.c	18 Jan 2003 15:55:52 -0000	1.23
+++ remote-vx.c	18 Feb 2003 20:24:50 -0000
@@ -67,7 +67,7 @@
 extern void vx_read_register ();
 extern void vx_write_register ();
 extern void symbol_file_command ();
-extern int stop_soon_quietly;	/* for wait_for_inferior */
+extern enum stop_kind stop_soon_quietly;	/* for wait_for_inferior */
 
 static int net_step ();
 static int net_ptrace_clnt_call ();	/* Forward decl */
@@ -243,9 +243,9 @@ vx_create_inferior (char *exec_file, cha
   /* Install inferior's terminal modes.  */
   target_terminal_inferior ();
 
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   wait_for_inferior ();		/* Get the task spawn event */
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
 
   /* insert_step_breakpoint ();  FIXME, do we need this?  */
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
Index: solib-irix.c
===================================================================
RCS file: /cvs/uberbaum/gdb/solib-irix.c,v
retrieving revision 1.1
diff -u -p -r1.1 solib-irix.c
--- solib-irix.c	27 Jul 2002 01:05:07 -0000	1.1
+++ solib-irix.c	18 Feb 2003 20:24:51 -0000
@@ -436,7 +436,7 @@ irix_solib_create_inferior_hook (void)
      out what we need to know about them. */
 
   clear_proceed_status ();
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   stop_signal = TARGET_SIGNAL_0;
   do
     {
@@ -462,7 +462,7 @@ irix_solib_create_inferior_hook (void)
      Delaying the resetting of stop_soon_quietly until after symbol loading
      suppresses the warning.  */
   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
   re_enable_breakpoints_in_shlibs ();
 }
 
Index: solib-osf.c
===================================================================
RCS file: /cvs/uberbaum/gdb/solib-osf.c,v
retrieving revision 1.4
diff -u -p -r1.4 solib-osf.c
--- solib-osf.c	2 Jul 2002 17:05:28 -0000	1.4
+++ solib-osf.c	18 Feb 2003 20:24:51 -0000
@@ -321,7 +321,7 @@ osf_solib_create_inferior_hook (void)
      out what we need to know about them. */
 
   clear_proceed_status ();
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   stop_signal = TARGET_SIGNAL_0;
   do
     {
@@ -337,7 +337,7 @@ osf_solib_create_inferior_hook (void)
      Delaying the resetting of stop_soon_quietly until after symbol loading
      suppresses the warning.  */
   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
 
   /* Enable breakpoints disabled (unnecessarily) by clear_solib().  */
   re_enable_breakpoints_in_shlibs ();
Index: solib-sunos.c
===================================================================
RCS file: /cvs/uberbaum/gdb/solib-sunos.c,v
retrieving revision 1.7
diff -u -p -r1.7 solib-sunos.c
--- solib-sunos.c	3 Feb 2003 20:39:41 -0000	1.7
+++ solib-sunos.c	18 Feb 2003 20:24:52 -0000
@@ -829,7 +829,7 @@ sunos_solib_create_inferior_hook (void)
      out what we need to know about them. */
 
   clear_proceed_status ();
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   stop_signal = TARGET_SIGNAL_0;
   do
     {
@@ -837,7 +837,7 @@ sunos_solib_create_inferior_hook (void)
       wait_for_inferior ();
     }
   while (stop_signal != TARGET_SIGNAL_TRAP);
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
 
   /* We are now either at the "mapping complete" breakpoint (or somewhere
      else, a condition we aren't prepared to deal with anyway), so adjust
Index: solib-svr4.c
===================================================================
RCS file: /cvs/uberbaum/gdb/solib-svr4.c,v
retrieving revision 1.29
diff -u -p -r1.29 solib-svr4.c
--- solib-svr4.c	18 Jan 2003 15:55:52 -0000	1.29
+++ solib-svr4.c	18 Feb 2003 20:24:53 -0000
@@ -1290,7 +1290,7 @@ svr4_solib_create_inferior_hook (void)
      out what we need to know about them. */
 
   clear_proceed_status ();
-  stop_soon_quietly = 1;
+  stop_soon_quietly = STOP_QUIETLY;
   stop_signal = TARGET_SIGNAL_0;
   do
     {
@@ -1298,7 +1298,7 @@ svr4_solib_create_inferior_hook (void)
       wait_for_inferior ();
     }
   while (stop_signal != TARGET_SIGNAL_TRAP);
-  stop_soon_quietly = 0;
+  stop_soon_quietly = NO_STOP_QUIETLY;
 #endif /* defined(_SCO_DS) */
 }
 


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