From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18568 invoked by alias); 18 Feb 2003 20:43:26 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 18542 invoked from network); 18 Feb 2003 20:43:25 -0000 Received: from unknown (HELO mx1.redhat.com) (172.16.49.200) by 172.16.49.205 with SMTP; 18 Feb 2003 20:43:25 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h1IKhPK00965 for ; Tue, 18 Feb 2003 15:43:25 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h1IKhPa11250; Tue, 18 Feb 2003 15:43:25 -0500 Received: from localhost.redhat.com (romulus-int.sfbay.redhat.com [172.16.27.46]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h1IKhO526055; Tue, 18 Feb 2003 15:43:24 -0500 Received: by localhost.redhat.com (Postfix, from userid 469) id 19004FF79; Tue, 18 Feb 2003 15:47:29 -0500 (EST) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15954.39904.805543.819269@localhost.redhat.com> Date: Tue, 18 Feb 2003 20:43:00 -0000 To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: Re: [RFC] PTRACE_ATTACH problem on new Linux kernels In-Reply-To: <3E52936A.3060706@redhat.com> References: <15953.34032.985446.344226@localhost.redhat.com> <20030218022401.14C7E3CF3@localhost.redhat.com> <15953.43345.841483.153044@localhost.redhat.com> <3E52936A.3060706@redhat.com> X-SW-Source: 2003-02/txt/msg00378.txt.bz2 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 * 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) */ }