summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/alpha-tdep.c2
-rw-r--r--gdb/fork-child.c5
-rw-r--r--gdb/infcmd.c7
-rw-r--r--gdb/inferior.h35
-rw-r--r--gdb/infrun.c29
-rw-r--r--gdb/mips-tdep.c2
-rw-r--r--gdb/remote-vx.c6
-rw-r--r--gdb/solib-irix.c4
-rw-r--r--gdb/solib-osf.c4
-rw-r--r--gdb/solib-sunos.c4
-rw-r--r--gdb/solib-svr4.c4
11 files changed, 75 insertions, 27 deletions
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index d3b58656e6c..7ef187f0324 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -557,7 +557,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;
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 0b14a946186..2ea56a35e9a 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -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;
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 38666905706..0c8b9437c66 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1910,8 +1910,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
/*
diff --git a/gdb/inferior.h b/gdb/inferior.h
index ae041f25004..34885973a09 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -390,12 +390,37 @@ extern enum step_over_calls_kind step_over_calls;
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?). */
+
+/* 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 int stop_soon_quietly;
+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. */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 74f1de1f672..92bbcdd2cb0 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -286,7 +286,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. */
@@ -659,7 +659,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... */
@@ -802,7 +802,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. */
@@ -1258,7 +1258,7 @@ handle_inferior_event (struct execution_control_state *ecs)
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. */
@@ -1757,7 +1757,9 @@ handle_inferior_event (struct execution_control_state *ecs)
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)
{
@@ -1765,12 +1767,27 @@ handle_inferior_event (struct execution_control_state *ecs)
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;
+ }
+
/* Don't even think about breakpoints
if just proceeded over a breakpoint.
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 59121f3c1aa..a9ead5d06ac 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -1821,7 +1821,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;
diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c
index 19153cf05b7..1d723f884f9 100644
--- a/gdb/remote-vx.c
+++ b/gdb/remote-vx.c
@@ -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, char *args, char **env)
/* 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);
diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c
index 1cfa452b06d..7d3bc9cb1bd 100644
--- a/gdb/solib-irix.c
+++ b/gdb/solib-irix.c
@@ -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 ();
}
diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c
index 6f43a8f0e49..634d490f0f6 100644
--- a/gdb/solib-osf.c
+++ b/gdb/solib-osf.c
@@ -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 ();
diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c
index 25682e02caa..427b33dd60d 100644
--- a/gdb/solib-sunos.c
+++ b/gdb/solib-sunos.c
@@ -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
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 78311086a3d..4d8de364f1f 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -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) */
}