/* Target-struct-independent code to start (run) and stop an inferior process.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993
+ Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* Notes on the algorithm used in wait_for_inferior to determine if we
- just did a subroutine call when stepping. We have the following
- information at that point:
-
- Current and previous (just before this step) pc.
- Current and previous sp.
- Current and previous start of current function.
-
- If the starts of the functions don't match, then
-
- a) We did a subroutine call.
-
- In this case, the pc will be at the beginning of a function.
-
- b) We did a subroutine return.
-
- Otherwise.
-
- c) We did a longjmp.
-
- If we did a longjump, we were doing "nexti", since a next would
- have attempted to skip over the assembly language routine in which
- the longjmp is coded and would have simply been the equivalent of a
- continue. I consider this ok behaivior. We'd like one of two
- things to happen if we are doing a nexti through the longjmp()
- routine: 1) It behaves as a stepi, or 2) It acts like a continue as
- above. Given that this is a special case, and that anybody who
- thinks that the concept of sub calls is meaningful in the context
- of a longjmp, I'll take either one. Let's see what happens.
-
- Acts like a subroutine return. I can handle that with no problem
- at all.
-
- -->So: If the current and previous beginnings of the current
- function don't match, *and* the pc is at the start of a function,
- we've done a subroutine call. If the pc is not at the start of a
- function, we *didn't* do a subroutine call.
-
- -->If the beginnings of the current and previous function do match,
- either:
-
- a) We just did a recursive call.
-
- In this case, we would be at the very beginning of a
- function and 1) it will have a prologue (don't jump to
- before prologue, or 2) (we assume here that it doesn't have
- a prologue) there will have been a change in the stack
- pointer over the last instruction. (Ie. it's got to put
- the saved pc somewhere. The stack is the usual place. In
- a recursive call a register is only an option if there's a
- prologue to do something with it. This is even true on
- register window machines; the prologue sets up the new
- window. It might not be true on a register window machine
- where the call instruction moved the register window
- itself. Hmmm. One would hope that the stack pointer would
- also change. If it doesn't, somebody send me a note, and
- I'll work out a more general theory.
- bug-gdb@prep.ai.mit.edu). This is true (albeit slipperly
- so) on all machines I'm aware of:
-
- m68k: Call changes stack pointer. Regular jumps don't.
-
- sparc: Recursive calls must have frames and therefor,
- prologues.
-
- vax: All calls have frames and hence change the
- stack pointer.
-
- b) We did a return from a recursive call. I don't see that we
- have either the ability or the need to distinguish this
- from an ordinary jump. The stack frame will be printed
- when and if the frame pointer changes; if we are in a
- function without a frame pointer, it's the users own
- lookout.
-
- c) We did a jump within a function. We assume that this is
- true if we didn't do a recursive call.
-
- d) We are in no-man's land ("I see no symbols here"). We
- don't worry about this; it will make calls look like simple
- jumps (and the stack frames will be printed when the frame
- pointer moves), which is a reasonably non-violent response.
-*/
-
#include "defs.h"
#include <string.h>
#include <ctype.h>
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
+#include "thread.h"
#include <signal.h>
static void
handle_command PARAMS ((char *, int));
-static void
-sig_print_info PARAMS ((int));
+static void sig_print_info PARAMS ((enum target_signal));
static void
sig_print_header PARAMS ((void));
void
resume (step, sig)
int step;
- int sig;
+ enum target_signal sig;
{
struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
QUIT;
+#ifdef CANNOT_STEP_BREAKPOINT
+ /* Most targets can step a breakpoint instruction, thus executing it
+ normally. But if this one cannot, just continue and we will hit
+ it anyway. */
+ if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
+ step = 0;
+#endif
+
#ifdef NO_SINGLE_STEP
if (step) {
single_step(sig); /* Do it the hard way, w/temp breakpoints */
DO_DEFERRED_STORES;
#endif
- target_resume (inferior_pid, step, sig);
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ target_resume (-1, step, sig);
discard_cleanups (old_cleanups);
}
void
proceed (addr, siggnal, step)
CORE_ADDR addr;
- int siggnal;
+ enum target_signal siggnal;
int step;
{
int oneproc = 0;
breakpoints_inserted = 1;
}
- /* Install inferior's terminal modes. */
- target_terminal_inferior ();
-
- if (siggnal >= 0)
+ if (siggnal != TARGET_SIGNAL_DEFAULT)
stop_signal = siggnal;
/* If this signal should not be seen by program,
give it zero. Used for debugging signals. */
- else if (stop_signal < NSIG && !signal_program[stop_signal])
- stop_signal= 0;
+ else if (!signal_program[stop_signal])
+ stop_signal = TARGET_SIGNAL_0;
/* Resume inferior. */
resume (oneproc || step || bpstat_should_step (), stop_signal);
trap_expected_after_continue = 0;
breakpoints_inserted = 0;
- mark_breakpoints_out ();
- stop_signal = 0; /* Don't confuse first call to proceed(). */
+ breakpoint_init_inferior ();
+
+ /* Don't confuse first call to proceed(). */
+ stop_signal = TARGET_SIGNAL_0;
}
static void
wait_for_inferior ()
{
struct cleanup *old_cleanups;
- WAITTYPE w;
+ struct target_waitstatus w;
int another_trap;
int random_signal;
CORE_ADDR stop_sp = 0;
CORE_ADDR stop_func_start;
+ CORE_ADDR stop_func_end;
char *stop_func_name;
CORE_ADDR prologue_pc = 0, tmp;
struct symtab_and_line sal;
int remove_breakpoints_on_following_step = 0;
int current_line;
+ struct symtab *current_symtab;
int handling_longjmp = 0; /* FIXME */
struct breakpoint *step_resume_breakpoint = NULL;
int pid;
&step_resume_breakpoint);
sal = find_pc_line(prev_pc, 0);
current_line = sal.line;
+ current_symtab = sal.symtab;
/* Are we stepping? */
#define CURRENTLY_STEPPING() ((step_resume_breakpoint == NULL \
flush_cached_frames ();
registers_changed ();
- pid = target_wait (&w);
-
-#ifdef SIGTRAP_STOP_AFTER_LOAD
+ pid = target_wait (-1, &w);
- /* Somebody called load(2), and it gave us a "trap signal after load".
- Ignore it gracefully. */
+ switch (w.kind)
+ {
+ case TARGET_WAITKIND_LOADED:
+ /* Ignore it gracefully. */
+ if (breakpoints_inserted)
+ {
+ mark_breakpoints_out ();
+ insert_breakpoints ();
+ }
+ resume (0, TARGET_SIGNAL_0);
+ continue;
- SIGTRAP_STOP_AFTER_LOAD (w);
-#endif
+ case TARGET_WAITKIND_SPURIOUS:
+ resume (0, TARGET_SIGNAL_0);
+ continue;
- /* See if the process still exists; clean up if it doesn't. */
- if (WIFEXITED (w))
- {
+ case TARGET_WAITKIND_EXITED:
target_terminal_ours (); /* Must do this before mourn anyway */
- if (WEXITSTATUS (w))
+ if (w.value.integer)
printf_filtered ("\nProgram exited with code 0%o.\n",
- (unsigned int)WEXITSTATUS (w));
+ (unsigned int)w.value.integer);
else
if (!batch_mode())
printf_filtered ("\nProgram exited normally.\n");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
target_mourn_inferior ();
#ifdef NO_SINGLE_STEP
one_stepped = 0;
#endif
stop_print_frame = 0;
- break;
- }
- else if (!WIFSTOPPED (w))
- {
- char *signame;
-
+ goto stop_stepping;
+
+ case TARGET_WAITKIND_SIGNALLED:
stop_print_frame = 0;
- stop_signal = WTERMSIG (w);
+ stop_signal = w.value.sig;
target_terminal_ours (); /* Must do this before mourn anyway */
target_kill (); /* kill mourns as well */
-#ifdef PRINT_RANDOM_SIGNAL
- printf_filtered ("\nProgram terminated: ");
- PRINT_RANDOM_SIGNAL (stop_signal);
-#else
- printf_filtered ("\nProgram terminated with signal ");
- signame = strsigno (stop_signal);
- if (signame == NULL)
- printf_filtered ("%d", stop_signal);
- else
- /* Do we need to print the number in addition to the name? */
- printf_filtered ("%s (%d)", signame, stop_signal);
- printf_filtered (", %s\n", safe_strsignal (stop_signal));
-#endif
+ printf_filtered ("\nProgram terminated with signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+
printf_filtered ("The program no longer exists.\n");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
#ifdef NO_SINGLE_STEP
one_stepped = 0;
#endif
+ goto stop_stepping;
+
+ case TARGET_WAITKIND_STOPPED:
+ /* This is the only case in which we keep going; the above cases
+ end in a continue or goto. */
break;
}
-
+
+ stop_signal = w.value.sig;
+
+ if (pid != inferior_pid)
+ {
+ int save_pid = inferior_pid;
+
+ inferior_pid = pid; /* Setup for target memory/regs */
+ registers_changed ();
+ stop_pc = read_pc ();
+ inferior_pid = save_pid;
+ registers_changed ();
+ }
+ else
+ stop_pc = read_pc ();
+
+ if (stop_signal == TARGET_SIGNAL_TRAP
+ && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+ {
+ if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
+ {
+ /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
+ if (breakpoints_inserted)
+ {
+ if (pid != inferior_pid)
+ {
+ int save_pid = inferior_pid;
+
+ inferior_pid = pid;
+ registers_changed ();
+ write_pc (stop_pc - DECR_PC_AFTER_BREAK);
+ inferior_pid = save_pid;
+ registers_changed ();
+ }
+ else
+ write_pc (stop_pc - DECR_PC_AFTER_BREAK);
+
+ remove_breakpoints ();
+ target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+ /* FIXME: What if a signal arrives instead of the single-step
+ happening? */
+ target_wait (pid, &w);
+ insert_breakpoints ();
+ }
+ target_resume (-1, 0, TARGET_SIGNAL_0);
+ continue;
+ }
+ else
+ if (pid != inferior_pid)
+ goto switch_thread;
+ }
+
if (pid != inferior_pid)
{
int printed = 0;
if (!in_thread_list (pid))
{
- fprintf (stderr, "[New %s]\n", target_pid_to_str (pid));
+ fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
add_thread (pid);
- target_resume (pid, 0, 0);
+ target_resume (-1, 0, TARGET_SIGNAL_0);
continue;
}
else
{
- stop_signal = WSTOPSIG (w);
-
- if (stop_signal >= NSIG || signal_print[stop_signal])
+ if (signal_print[stop_signal])
{
char *signame;
printed = 1;
target_terminal_ours_for_output ();
- printf_filtered ("\nProgram received signal ");
- signame = strsigno (stop_signal);
- if (signame == NULL)
- printf_filtered ("%d", stop_signal);
- else
- printf_filtered ("%s (%d)", signame, stop_signal);
- printf_filtered (", %s\n", safe_strsignal (stop_signal));
-
- fflush (stdout);
+ printf_filtered ("\nProgram received signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+ gdb_flush (gdb_stdout);
}
- if (stop_signal >= NSIG || signal_stop[stop_signal])
+ if (stop_signal == TARGET_SIGNAL_TRAP
+ || signal_stop[stop_signal])
{
+switch_thread:
inferior_pid = pid;
printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
/* Clear the signal if it should not be passed. */
if (signal_program[stop_signal] == 0)
- stop_signal = 0;
+ stop_signal = TARGET_SIGNAL_0;
target_resume (pid, 0, stop_signal);
continue;
continue;
}
- stop_pc = read_pc ();
set_current_frame ( create_new_frame (read_fp (), stop_pc));
stop_frame_address = FRAME_FP (get_current_frame ());
/* Don't care about return value; stop_func_start and stop_func_name
will both be 0 if it doesn't work. */
find_pc_partial_function (stop_pc, &stop_func_name, &stop_func_start,
- (CORE_ADDR *)NULL);
+ &stop_func_end);
stop_func_start += FUNCTION_START_OFFSET;
another_trap = 0;
bpstat_clear (&stop_bpstat);
3) set random_signal to 1, and the decision between 1 and 2
will be made according to the signal handling tables. */
- stop_signal = WSTOPSIG (w);
-
/* First, distinguish signals caused by the debugger from signals
that have to do with the program's own actions.
Note that breakpoint insns may cause SIGTRAP or SIGILL
Here we detect when a SIGILL or SIGEMT is really a breakpoint
and change it to SIGTRAP. */
- if (stop_signal == SIGTRAP
+ if (stop_signal == TARGET_SIGNAL_TRAP
|| (breakpoints_inserted &&
- (stop_signal == SIGILL
-#ifdef SIGEMT
- || stop_signal == SIGEMT
-#endif
+ (stop_signal == TARGET_SIGNAL_ILL
+ || stop_signal == TARGET_SIGNAL_EMT
))
|| stop_soon_quietly)
{
- if (stop_signal == SIGTRAP && stop_after_trap)
+ if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
{
stop_print_frame = 0;
break;
and end up in sigtramp, then step_resume_breakpoint
will be set and we should check whether we've hit the
step breakpoint. */
- if (stop_signal == SIGTRAP && trap_expected
+ if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
&& step_resume_breakpoint == NULL)
bpstat_clear (&stop_bpstat);
else
stop_print_frame = 1;
}
- if (stop_signal == SIGTRAP)
+ if (stop_signal == TARGET_SIGNAL_TRAP)
random_signal
= !(bpstat_explains_signal (stop_bpstat)
|| trap_expected
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
);
if (!random_signal)
- stop_signal = SIGTRAP;
+ stop_signal = TARGET_SIGNAL_TRAP;
}
}
else
stopped_by_random_signal = 1;
- if (stop_signal >= NSIG
- || signal_print[stop_signal])
+ if (signal_print[stop_signal])
{
char *signame;
printed = 1;
target_terminal_ours_for_output ();
-#ifdef PRINT_RANDOM_SIGNAL
- PRINT_RANDOM_SIGNAL (stop_signal);
-#else
- printf_filtered ("\nProgram received signal ");
- signame = strsigno (stop_signal);
- if (signame == NULL)
- printf_filtered ("%d", stop_signal);
- else
- /* Do we need to print the number as well as the name? */
- printf_filtered ("%s (%d)", signame, stop_signal);
- printf_filtered (", %s\n", safe_strsignal (stop_signal));
-#endif /* PRINT_RANDOM_SIGNAL */
- fflush (stdout);
+ printf_filtered ("\nProgram received signal %s, %s.\n",
+ target_signal_to_name (stop_signal),
+ target_signal_to_string (stop_signal));
+ gdb_flush (gdb_stdout);
}
- if (stop_signal >= NSIG
- || signal_stop[stop_signal])
+ if (signal_stop[stop_signal])
break;
/* If not going to stop, give terminal back
if we took it away. */
/* Clear the signal if it should not be passed. */
if (signal_program[stop_signal] == 0)
- stop_signal = 0;
+ stop_signal = TARGET_SIGNAL_0;
/* I'm not sure whether this needs to be check_sigtramp2 or
whether it could/should be keep_going. */
cleanup chain, so no need to worry about it here. */
goto stop_stepping;
+ case BPSTAT_WHAT_LAST:
+ /* Not a real code, but listed here to shut up gcc -Wall. */
+
case BPSTAT_WHAT_KEEP_CHECKING:
break;
}
SKIP_PROLOGUE (prologue_pc);
}
- /* ==> See comments at top of file on this algorithm. <==*/
-
- 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))
+ if ((/* Might be a non-recursive call. If the symbols are missing
+ enough that stop_func_start == prev_func_start even though
+ they are really two functions, we will treat some calls as
+ jumps. */
+ stop_func_start != prev_func_start
+
+ /* Might be a recursive call if either we have a prologue
+ or the call instruction itself saves the PC on the stack. */
+ || prologue_pc != stop_func_start
+ || stop_sp != prev_sp)
+ && (/* PC is completely out of bounds of any known objfiles. Treat
+ like a subroutine call. */
+ ! stop_func_start
+
+ /* If we do a call, we will be at the start of a function... */
+ || stop_pc == stop_func_start
+
+ /* ...except on the Alpha with -O (and also Irix 5 and
+ perhaps others), in which we might call the address
+ after the load of gp. Since prologues don't contain
+ calls, we can't return to within one, and we don't
+ jump back into them, so this check is OK. */
+
+ || stop_pc < prologue_pc
+
+ /* If we end up in certain places, it means we did a subroutine
+ call. I'm not completely sure this is necessary now that we
+ have the above checks with stop_func_start (and now that
+ find_pc_partial_function is pickier). */
+ || IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)
+
+ /* If none of the above apply, it is a jump within a function,
+ or a return from a subroutine. The other case is longjmp,
+ which can no longer happen here as long as the
+ handling_longjmp stuff is working. */
+ ))
{
/* It's a subroutine call. */
the end of the prologue, even if that involves jumps
(as it seems to on the vax under 4.2). */
/* If the prologue ends in the middle of a source line,
- continue to the end of that source line.
- Otherwise, just go to end of prologue. */
+ continue to the end of that source line (if it is still
+ within the function). Otherwise, just go to end of prologue. */
#ifdef PROLOGUE_FIRSTLINE_OVERLAP
/* no, don't either. It skips any code that's
legitimately on the first line. */
#else
- if (sal.end && sal.pc != stop_func_start)
+ if (sal.end && sal.pc != stop_func_start && sal.end < stop_func_end)
stop_func_start = sal.end;
#endif
goto keep_going;
}
- /* We've wandered out of the step range (but haven't done a
- subroutine call or return). (Is that true? I think we get
- here if we did a return and maybe a longjmp). */
+ /* We've wandered out of the step range. */
sal = find_pc_line(stop_pc, 0);
break;
}
- if (stop_pc == sal.pc && current_line != sal.line)
+ if (stop_pc == sal.pc
+ && (current_line != sal.line || current_symtab != sal.symtab))
{
/* We are at the start of a different line. So stop. Note that
we don't stop if we step into the middle of a different line.
(We might not be in the original line, but if we entered a
new line in mid-statement, we continue stepping. This makes
things like for(;;) statements work better.) */
+
+ if (stop_func_end && sal.end >= stop_func_end)
+ {
+ /* If this is the last line of the function, don't keep stepping
+ (it would probably step us out of the function).
+ This is particularly necessary for a one-line function,
+ in which after skipping the prologue we better stop even though
+ we will be in mid-line. */
+ stop_step = 1;
+ break;
+ }
step_range_start = sal.pc;
step_range_end = sal.end;
goto keep_going;
/* If we did not do break;, it means we should keep
running the inferior and not return to debugger. */
- if (trap_expected && stop_signal != SIGTRAP)
+ if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP)
{
/* We took a signal (which we are supposed to pass through to
the inferior, else we'd have done a break above) and we
trap_expected = another_trap;
- if (stop_signal == SIGTRAP)
- stop_signal = 0;
+ if (stop_signal == TARGET_SIGNAL_TRAP)
+ stop_signal = TARGET_SIGNAL_0;
#ifdef SHIFT_INST_REGS
/* I'm not sure when this following segment applies. I do know, now,
that we shouldn't rewrite the regs when we were stopped by a
random signal from the inferior process. */
+ /* FIXME: Shouldn't this be based on the valid bit of the SXIP?
+ (this is only used on the 88k). */
if (!bpstat_explains_signal (stop_bpstat)
- && (stop_signal != SIGCLD)
+ && (stop_signal != TARGET_SIGNAL_CHLD)
&& !stopped_by_random_signal)
SHIFT_INST_REGS();
#endif /* SHIFT_INST_REGS */
/* Make sure that the current_frame's pc is correct. This
is a correction for setting up the frame info before doing
DECR_PC_AFTER_BREAK */
- if (target_has_execution)
+ if (target_has_execution && get_current_frame())
(get_current_frame ())->pc = read_pc ();
if (breakpoints_failed)
POP_FRAME ends with a setting of the current frame, so we
can use that next. */
POP_FRAME;
+ /* Set stop_pc to what it was before we called the function. Can't rely
+ on restore_inferior_status because that only gets called if we don't
+ stop in the called function. */
+ stop_pc = read_pc();
select_frame (get_current_frame (), 0);
}
}
int signal_stop_state (signo)
int signo;
{
- return ((signo >= 0 && signo < NSIG) ? signal_stop[signo] : 0);
+ return signal_stop[signo];
}
int signal_print_state (signo)
int signo;
{
- return ((signo >= 0 && signo < NSIG) ? signal_print[signo] : 0);
+ return signal_print[signo];
}
int signal_pass_state (signo)
int signo;
{
- return ((signo >= 0 && signo < NSIG) ? signal_program[signo] : 0);
+ return signal_program[signo];
}
static void
sig_print_header ()
{
- printf_filtered ("Signal\t\tStop\tPrint\tPass to program\tDescription\n");
+ printf_filtered ("\
+Signal Stop\tPrint\tPass to program\tDescription\n");
}
static void
-sig_print_info (number)
- int number;
+sig_print_info (oursig)
+ enum target_signal oursig;
{
- char *name;
-
- if ((name = strsigno (number)) == NULL)
- printf_filtered ("%d\t\t", number);
- else
- 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", safe_strsignal (number));
+ char *name = target_signal_to_name (oursig);
+ printf_filtered ("%s", name);
+ printf_filtered ("%*.*s ", 13 - strlen (name), 13 - strlen (name),
+ " ");
+ printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
+ printf_filtered ("%s\n", target_signal_to_string (oursig));
}
/* Specify how various signals in the inferior should be handled. */
char **argv;
int digits, wordlen;
int sigfirst, signum, siglast;
+ enum target_signal oursig;
int allsigs;
int nsigs;
unsigned char *sigs;
/* Allocate and zero an array of flags for which signals to handle. */
- nsigs = signo_max () + 1;
+ nsigs = (int)TARGET_SIGNAL_LAST;
sigs = (unsigned char *) alloca (nsigs);
memset (sigs, 0, nsigs);
}
old_chain = make_cleanup (freeargv, (char *) argv);
- /* Walk through the args, looking for signal numbers, signal names, and
+ /* Walk through the args, looking for signal oursigs, signal names, and
actions. Signal numbers and signal names may be interspersed with
actions, with the actions being performed for all signals cumulatively
specified. Signal ranges can be specified as <LOW>-<HIGH>. */
}
else if (digits > 0)
{
+ /* It is numeric. The numeric signal refers to our own internal
+ signal numbering from target.h, not to host/target signal number.
+ This is a feature; users really should be using symbolic names
+ anyway, and the common ones like SIGHUP, SIGINT, SIGALRM, etc.
+ will work right anyway. */
+
sigfirst = siglast = atoi (*argv);
if ((*argv)[digits] == '-')
{
error ("Signal %d not in range 0-%d", siglast, nsigs - 1);
}
}
- else if ((signum = strtosigno (*argv)) != 0)
- {
- sigfirst = siglast = signum;
- }
else
{
- /* Not a number and not a recognized flag word => complain. */
- error ("Unrecognized or ambiguous flag word: \"%s\".", *argv);
+ oursig = target_signal_from_name (*argv);
+ if (oursig != TARGET_SIGNAL_UNKNOWN)
+ {
+ sigfirst = siglast = (int)oursig;
+ }
+ else
+ {
+ /* Not a number and not a recognized flag word => complain. */
+ error ("Unrecognized or ambiguous flag word: \"%s\".", *argv);
+ }
}
/* If any signal numbers or symbol names were found, set flags for
for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
{
- switch (signum)
+ switch ((enum target_signal)signum)
{
- case SIGTRAP:
- case SIGINT:
+ case TARGET_SIGNAL_TRAP:
+ case TARGET_SIGNAL_INT:
if (!allsigs && !sigs[signum])
{
- if (query ("%s is used by the debugger.\nAre you sure you want to change it? ", strsigno (signum)))
+ if (query ("%s is used by the debugger.\n\
+Are you sure you want to change it? ",
+ target_signal_to_name
+ ((enum target_signal)signum)))
{
sigs[signum] = 1;
}
else
{
- printf ("Not confirmed, unchanged.\n");
- fflush (stdout);
+ printf_unfiltered ("Not confirmed, unchanged.\n");
+ gdb_flush (gdb_stdout);
}
}
break;
argv++;
}
- target_notice_signals();
+ target_notice_signals(inferior_pid);
if (from_tty)
{
do_cleanups (old_chain);
}
-/* Print current contents of the tables set by the handle command. */
+/* Print current contents of the tables set by the handle command.
+ It is possible we should just be printing signals actually used
+ by the current target (but for things to work right when switching
+ targets, all signals should be in the signal tables). */
static void
signals_info (signum_exp, from_tty)
char *signum_exp;
int from_tty;
{
- register int i;
+ enum target_signal oursig;
sig_print_header ();
if (signum_exp)
{
/* First see if this is a symbol name. */
- i = strtosigno (signum_exp);
- if (i == 0)
+ oursig = target_signal_from_name (signum_exp);
+ if (oursig == TARGET_SIGNAL_UNKNOWN)
{
/* Nope, maybe it's an address which evaluates to a signal
number. */
- i = parse_and_eval_address (signum_exp);
- if (i >= NSIG || i < 0)
+ /* The numeric signal refers to our own internal
+ signal numbering from target.h, not to host/target signal number.
+ This is a feature; users really should be using symbolic names
+ anyway, and the common ones like SIGHUP, SIGINT, SIGALRM, etc.
+ will work right anyway. */
+ int i = parse_and_eval_address (signum_exp);
+ if (i >= (int)TARGET_SIGNAL_LAST
+ || i < 0
+ || i == (int)TARGET_SIGNAL_UNKNOWN
+ || i == (int)TARGET_SIGNAL_DEFAULT)
error ("Signal number out of bounds.");
+ oursig = (enum target_signal)i;
}
- sig_print_info (i);
+ sig_print_info (oursig);
return;
}
printf_filtered ("\n");
- for (i = 0; i < NSIG; i++)
+ /* These ugly casts brought to you by the native VAX compiler. */
+ for (oursig = 0;
+ (int)oursig < (int)TARGET_SIGNAL_LAST;
+ oursig = (enum target_signal)((int)oursig + 1))
{
QUIT;
- sig_print_info (i);
+ if (oursig != TARGET_SIGNAL_UNKNOWN
+ && oursig != TARGET_SIGNAL_DEFAULT
+ && oursig != TARGET_SIGNAL_0)
+ sig_print_info (oursig);
}
printf_filtered ("\nUse the \"handle\" command to change these tables.\n");
This allows you to set a list of commands to be run each time execution\n\
of the program stops.", &cmdlist);
- numsigs = signo_max () + 1;
- signal_stop = (unsigned char *)
- xmalloc (sizeof (signal_stop[0]) * numsigs);
- signal_print = (unsigned char *)
- xmalloc (sizeof (signal_print[0]) * numsigs);
+ numsigs = (int)TARGET_SIGNAL_LAST;
+ signal_stop = (unsigned char *)
+ xmalloc (sizeof (signal_stop[0]) * numsigs);
+ signal_print = (unsigned char *)
+ xmalloc (sizeof (signal_print[0]) * numsigs);
signal_program = (unsigned char *)
- xmalloc (sizeof (signal_program[0]) * numsigs);
+ xmalloc (sizeof (signal_program[0]) * numsigs);
for (i = 0; i < numsigs; i++)
{
signal_stop[i] = 1;
/* Signals caused by debugger's own actions
should not be given to the program afterwards. */
- signal_program[SIGTRAP] = 0;
- signal_program[SIGINT] = 0;
+ signal_program[TARGET_SIGNAL_TRAP] = 0;
+ signal_program[TARGET_SIGNAL_INT] = 0;
/* Signals that are not errors should not normally enter the debugger. */
-#ifdef SIGALRM
- signal_stop[SIGALRM] = 0;
- signal_print[SIGALRM] = 0;
-#endif /* SIGALRM */
-#ifdef SIGVTALRM
- signal_stop[SIGVTALRM] = 0;
- signal_print[SIGVTALRM] = 0;
-#endif /* SIGVTALRM */
-#ifdef SIGPROF
- signal_stop[SIGPROF] = 0;
- signal_print[SIGPROF] = 0;
-#endif /* SIGPROF */
-#ifdef SIGCHLD
- signal_stop[SIGCHLD] = 0;
- signal_print[SIGCHLD] = 0;
-#endif /* SIGCHLD */
-#ifdef SIGCLD
- signal_stop[SIGCLD] = 0;
- signal_print[SIGCLD] = 0;
-#endif /* SIGCLD */
-#ifdef SIGIO
- signal_stop[SIGIO] = 0;
- signal_print[SIGIO] = 0;
-#endif /* SIGIO */
-#ifdef SIGURG
- signal_stop[SIGURG] = 0;
- signal_print[SIGURG] = 0;
-#endif /* SIGURG */
+ signal_stop[TARGET_SIGNAL_ALRM] = 0;
+ signal_print[TARGET_SIGNAL_ALRM] = 0;
+ signal_stop[TARGET_SIGNAL_VTALRM] = 0;
+ signal_print[TARGET_SIGNAL_VTALRM] = 0;
+ signal_stop[TARGET_SIGNAL_PROF] = 0;
+ signal_print[TARGET_SIGNAL_PROF] = 0;
+ signal_stop[TARGET_SIGNAL_CHLD] = 0;
+ signal_print[TARGET_SIGNAL_CHLD] = 0;
+ signal_stop[TARGET_SIGNAL_IO] = 0;
+ signal_print[TARGET_SIGNAL_IO] = 0;
+ signal_stop[TARGET_SIGNAL_POLL] = 0;
+ signal_print[TARGET_SIGNAL_POLL] = 0;
+ signal_stop[TARGET_SIGNAL_URG] = 0;
+ signal_print[TARGET_SIGNAL_URG] = 0;
}