#include "breakpoint.h"
#include "wait.h"
#include "gdbcore.h"
-#include "signame.h"
#include "command.h"
#include "terminal.h" /* For #ifdef TIOCGPGRP and new_tty */
#include "target.h"
/* Prototypes for local functions */
static void
-signals_info PARAMS ((char *));
+signals_info PARAMS ((char *, int));
static void
handle_command PARAMS ((char *, int));
#define SKIP_TRAMPOLINE_CODE(pc) 0
#endif
+/* For SVR4 shared libraries, each call goes through a small piece of
+ trampoline code in the ".init" section. IN_SOLIB_TRAMPOLINE evaluates
+ to nonzero if we are current stopped in one of these. */
+#ifndef IN_SOLIB_TRAMPOLINE
+#define IN_SOLIB_TRAMPOLINE(pc,name) 0
+#endif
+
+/* Notify other parts of gdb that might care that signal handling may
+ have changed for one or more signals. */
+#ifndef NOTICE_SIGNAL_HANDLING_CHANGE
+#define NOTICE_SIGNAL_HANDLING_CHANGE /* No actions */
+#endif
#ifdef TDESC
#include "tdesc.h"
/* Tables of how to react to signals; the user sets them. */
-static char signal_stop[NSIG];
-static char signal_print[NSIG];
-static char signal_program[NSIG];
+static char *signal_stop;
+static char *signal_print;
+static char *signal_program;
/* Nonzero if breakpoints are now inserted in the inferior. */
/* Nonstatic for initialization during xxx_create_inferior. FIXME. */
{
int pid;
char *shell_command;
- extern int sys_nerr;
- extern char *sys_errlist[];
char *shell_file;
static char default_shell_file[] = SHELL_FILE;
int len;
for the inferior. */
#ifdef USE_PROC_FS
- proc_set_exec_trap (); /* Use SVR4 /proc interface */
+ /* Use SVR4 /proc interface */
+ proc_set_exec_trap ();
#else
- call_ptrace (0, 0, 0, 0); /* "Trace me, Dr. Memory!" */
+ /* "Trace me, Dr. Memory!" */
+ call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
#endif
/* There is no execlpe call, so we have to set the environment
execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
fprintf (stderr, "Cannot exec %s: %s.\n", shell_file,
- errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+ safe_strerror (errno));
fflush (stderr);
_exit (0177);
}
correct program, and are poised at the first instruction of the
new program. */
#ifdef SOLIB_CREATE_INFERIOR_HOOK
- SOLIB_CREATE_INFERIOR_HOOK ();
+ SOLIB_CREATE_INFERIOR_HOOK (pid);
#endif
/* Should this perhaps just be a "proceed" call? FIXME */
#else
pid = atoi (args);
+ if (pid == getpid()) /* Trying to masturbate? */
+ error ("I refuse to debug myself!");
+
if (target_has_execution)
{
if (query ("A program is being debugged already. Kill it? "))
target_wait (&w);
+#ifdef SIGTRAP_STOP_AFTER_LOAD
+
+ /* Somebody called load(2), and it gave us a "trap signal after load".
+ Ignore it gracefully. */
+
+ SIGTRAP_STOP_AFTER_LOAD (w);
+#endif
+
/* See if the process still exists; clean up if it doesn't. */
if (WIFEXITED (w))
{
target_terminal_ours (); /* Must do this before mourn anyway */
if (WEXITSTATUS (w))
- printf ("\nProgram exited with code 0%o.\n",
+ printf_filtered ("\nProgram exited with code 0%o.\n",
(unsigned int)WEXITSTATUS (w));
else
if (!batch_mode())
- printf ("\nProgram exited normally.\n");
+ printf_filtered ("\nProgram exited normally.\n");
fflush (stdout);
target_mourn_inferior ();
#ifdef NO_SINGLE_STEP
target_terminal_ours (); /* Must do this before mourn anyway */
target_kill (); /* kill mourns as well */
#ifdef PRINT_RANDOM_SIGNAL
- printf ("\nProgram terminated: ");
+ printf_filtered ("\nProgram terminated: ");
PRINT_RANDOM_SIGNAL (stop_signal);
#else
- printf ("\nProgram terminated with signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
+ printf_filtered ("\nProgram terminated with signal %d, %s\n",
+ stop_signal, safe_strsignal (stop_signal));
#endif
- printf ("The inferior process no longer exists.\n");
+ printf_filtered ("The inferior process no longer exists.\n");
fflush (stdout);
#ifdef NO_SINGLE_STEP
one_stepped = 0;
if (stop_signal == SIGTRAP
|| (breakpoints_inserted &&
(stop_signal == SIGILL
- || stop_signal == SIGEMT))
+#ifdef SIGEMT
+ || stop_signal == SIGEMT
+#endif
+ ))
|| stop_soon_quietly)
{
if (stop_signal == SIGTRAP && stop_after_trap)
#ifdef PRINT_RANDOM_SIGNAL
PRINT_RANDOM_SIGNAL (stop_signal);
#else
- printf ("\nProgram received signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
+ printf_filtered ("\nProgram received signal %d, %s\n",
+ stop_signal, safe_strsignal (stop_signal));
#endif /* PRINT_RANDOM_SIGNAL */
fflush (stdout);
}
#if 0
if (* step_frame_address == 0
|| (step_frame_address == stop_frame_address))
-#endif 0
+#endif
{
remove_step_breakpoint ();
step_resume_break_address = 0;
/* ==> See comments at top of file on this algorithm. <==*/
- if (stop_pc == stop_func_start
- && (stop_func_start != prev_func_start
- || prologue_pc != stop_func_start
- || stop_sp != prev_sp))
+ if ((stop_pc == stop_func_start
+ || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name))
+ && (stop_func_start != prev_func_start
+ || prologue_pc != stop_func_start
+ || stop_sp != prev_sp))
{
/* It's a subroutine call.
(0) If we are not stepping over any calls ("stepi"), we
goto step_over_function;
tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
- if (tmp != NULL)
+ if (tmp != 0)
stop_func_start = tmp;
if (find_pc_function (stop_func_start) != 0)
step_range_end = sal.end;
goto save_pc;
}
- abort(); /* We never fall through here */
+ /* We never fall through here */
}
if (trap_expected
{
target_terminal_ours_for_output ();
print_sys_errmsg ("ptrace", breakpoints_failed);
- printf ("Stopped; cannot insert breakpoints.\n\
+ printf_filtered ("Stopped; cannot insert breakpoints.\n\
The same program may be running in another process.\n");
}
if (remove_breakpoints ())
{
target_terminal_ours_for_output ();
- printf ("Cannot remove breakpoints because program is no longer writable.\n\
+ printf_filtered ("Cannot remove breakpoints because program is no longer writable.\n\
It might be running in another process.\n\
Further execution is probably impossible.\n");
}
step_resume_break_shadow);
}
\f
+int signal_stop_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_stop[signo] : 0);
+}
+
+int signal_print_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_print[signo] : 0);
+}
+
+int signal_pass_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_program[signo] : 0);
+}
+
static void
sig_print_header ()
{
sig_print_info (number)
int number;
{
- char *abbrev = sig_abbrev(number);
- if (abbrev == NULL)
+ char *name;
+
+ if ((name = strsigno (number)) == NULL)
printf_filtered ("%d\t\t", number);
else
- printf_filtered ("SIG%s (%d)\t", abbrev, number);
+ printf_filtered ("%s (%d)\t", name, number);
printf_filtered ("%s\t", signal_stop[number] ? "Yes" : "No");
printf_filtered ("%s\t", signal_print[number] ? "Yes" : "No");
printf_filtered ("%s\t\t", signal_program[number] ? "Yes" : "No");
- printf_filtered ("%s\n", sys_siglist[number]);
+ printf_filtered ("%s\n", safe_strsignal (number));
}
/* Specify how various signals in the inferior should be handled. */
{
/* Numeric. */
signum = atoi (p);
- if (signum <= 0 || signum >= NSIG)
+ if (signum <= 0 || signum > signo_max ())
{
p[wordlen] = '\0';
error ("Invalid signal %s given as argument to \"handle\".", p);
else
{
/* Symbolic. */
- signum = sig_number (p);
- if (signum == -1)
+ signum = strtosigno (p);
+ if (signum == 0)
error ("No such signal \"%s\"", p);
}
if (signum == SIGTRAP || signum == SIGINT)
{
- if (!query ("SIG%s is used by the debugger.\nAre you sure you want to change it? ", sig_abbrev (signum)))
+ if (!query ("%s is used by the debugger.\nAre you sure you want to change it? ", strsigno (signum)))
error ("Not confirmed.");
}
}
/* Not a number and not a recognized flag word => complain. */
else
{
- error ("Unrecognized flag word: \"%s\".", p);
+ error ("Unrecognized or ambiguous flag word: \"%s\".", p);
}
/* Find start of next word. */
while (*p == ' ' || *p == '\t') p++;
}
+ NOTICE_SIGNAL_HANDLING_CHANGE;
+
if (from_tty)
{
/* Show the results. */
/* Print current contents of the tables set by the handle command. */
static void
-signals_info (signum_exp)
+signals_info (signum_exp, from_tty)
char *signum_exp;
+ int from_tty;
{
register int i;
sig_print_header ();
if (signum_exp)
{
/* First see if this is a symbol name. */
- i = sig_number (signum_exp);
- if (i == -1)
+ i = strtosigno (signum_exp);
+ if (i == 0)
{
/* Nope, maybe it's an address which evaluates to a signal
number. */
_initialize_infrun ()
{
register int i;
+ register int numsigs;
add_info ("signals", signals_info,
"What debugger does when program gets various signals.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Pass and Stop may be combined.");
- for (i = 0; i < NSIG; i++)
+ numsigs = signo_max () + 1;
+ signal_stop = xmalloc (sizeof (signal_stop[0]) * numsigs);
+ signal_print = xmalloc (sizeof (signal_print[0]) * numsigs);
+ signal_program = xmalloc (sizeof (signal_program[0]) * numsigs);
+ for (i = 0; i < numsigs; i++)
{
signal_stop[i] = 1;
signal_print[i] = 1;