#include "defs.h"
#include "arch-utils.h"
#include <signal.h>
-#include <string.h>
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "block.h"
#include "solib.h"
#include <ctype.h>
-#include "gdb_assert.h"
#include "observer.h"
#include "target-descriptions.h"
#include "user-regs.h"
-#include "exceptions.h"
#include "cli/cli-decode.h"
#include "gdbthread.h"
#include "valprint.h"
proceed ((CORE_ADDR) -1, oursig, 0);
}
+/* Queue a signal to be delivered to the current thread. */
+
+static void
+queue_signal_command (char *signum_exp, int from_tty)
+{
+ enum gdb_signal oursig;
+ struct thread_info *tp;
+
+ ERROR_NO_INFERIOR;
+ ensure_not_tfind_mode ();
+ ensure_valid_thread ();
+ ensure_not_running ();
+
+ if (signum_exp == NULL)
+ error_no_arg (_("signal number"));
+
+ /* It would be even slicker to make signal names be valid expressions,
+ (the type could be "enum $signal" or some such), then the user could
+ assign them to convenience variables. */
+ oursig = gdb_signal_from_name (signum_exp);
+
+ if (oursig == GDB_SIGNAL_UNKNOWN)
+ {
+ /* No, try numeric. */
+ int num = parse_and_eval_long (signum_exp);
+
+ if (num == 0)
+ oursig = GDB_SIGNAL_0;
+ else
+ oursig = gdb_signal_from_command (num);
+ }
+
+ if (oursig != GDB_SIGNAL_0
+ && !signal_pass_state (oursig))
+ error (_("Signal handling set to not pass this signal to the program."));
+
+ tp = inferior_thread ();
+ tp->suspend.stop_signal = oursig;
+}
+
/* Continuation args to be passed to the "until" command
continuation. */
struct until_next_continuation_args
error (_("Execution is not within a known function."));
tp->control.step_range_start = BMSYMBOL_VALUE_ADDRESS (msymbol);
- tp->control.step_range_end = pc;
+ /* The upper-bound of step_range is exclusive. In order to make PC
+ within the range, set the step_range_end with PC + 1. */
+ tp->control.step_range_end = pc + 1;
}
else
{
gdb_signal_to_string (tp->suspend.stop_signal));
}
- if (!from_tty)
+ if (from_tty)
{
printf_filtered (_("Type \"info stack\" or \"info "
"registers\" for more information.\n"));
do_cleanups (old_chain);
}
-/*
- * TODO:
- * Should save/restore the tty state since it might be that the
- * program to be debugged was started on this tty and it wants
- * the tty in some state other than what we want. If it's running
- * on another terminal or without a terminal, then saving and
- * restoring the tty state is a harmless no-op.
- * This only needs to be done if we are attaching to a process.
- */
-
/* attach_command --
takes a program started up outside of gdb and ``attaches'' to it.
This stops it cold in its tracks and allows us to start debugging it.
\n\
An argument of \"0\" means continue the program without sending it a signal.\n\
This is useful in cases where the program stopped because of a signal,\n\
-and you want to resume the program while discarding the signal."));
+and you want to resume the program while discarding the signal.\n\
+\n\
+In a multi-threaded program the signal is delivered to, or discarded from,\n\
+the current thread only."));
+ set_cmd_completer (c, signal_completer);
+
+ c = add_com ("queue-signal", class_run, queue_signal_command, _("\
+Queue a signal to be delivered to the current thread when it is resumed.\n\
+Usage: queue-signal SIGNAL\n\
+The SIGNAL argument is processed the same as the handle command.\n\
+It is an error if the handling state of SIGNAL is \"nopass\".\n\
+\n\
+An argument of \"0\" means remove any currently queued signal from\n\
+the current thread. This is useful in cases where the program stopped\n\
+because of a signal, and you want to resume it while discarding the signal.\n\
+\n\
+In a multi-threaded program the signal is queued with, or discarded from,\n\
+the current thread only."));
set_cmd_completer (c, signal_completer);
add_com ("stepi", class_run, stepi_command, _("\