diff options
author | Doug Evans <xdje42@gmail.com> | 2014-09-13 21:44:00 -0700 |
---|---|---|
committer | Doug Evans <xdje42@gmail.com> | 2014-09-13 21:44:00 -0700 |
commit | 81219e5358e6238d3810136690a0c0b2cd20955e (patch) | |
tree | 19573767c0e0915e7e0fd670a0e544dcf26dfc3a /gdb/infcmd.c | |
parent | d4b38d2d057a5b8a35bc052e4f43b02b53c40f89 (diff) | |
download | gdb-81219e5358e6238d3810136690a0c0b2cd20955e.zip gdb-81219e5358e6238d3810136690a0c0b2cd20955e.tar.gz gdb-81219e5358e6238d3810136690a0c0b2cd20955e.tar.bz2 |
New command queue-signal.
If I want to change the signalled state of multiple threads
it's a bit cumbersome to do with the "signal" command.
What you really want is a way to set the signal state of the
desired threads and then just do "continue".
This patch adds a new command, queue-signal, to accomplish this.
Basically "signal N" == "queue-signal N" + "continue".
That's not precisely true in that "signal" can be used to inject
any signal, including signals set to "nopass"; whereas "queue-signal"
just queues the signal as if the thread stopped because of it.
"nopass" handling is done when the thread is resumed which
"queue-signal" doesn't do.
One could add extra complexity to allow queue-signal to be used to
deliver "nopass" signals like the "signal" command. I have no current
need for it so in the interests of incremental complexity, I have
left such support out and just have the code flag an error if one
tries to queue a nopass signal.
gdb/ChangeLog:
* NEWS: Mention new "queue-signal" command.
* infcmd.c (queue_signal_command): New function.
(_initialize_infcmd): Add new queue-signal command.
gdb/doc/ChangeLog:
* gdb.texinfo (Signaling): Document new queue-signal command.
gdb/testsuite/ChangeLog:
* gdb.threads/queue-signal.c: New file.
* gdb.threads/queue-signal.exp: New file.
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r-- | gdb/infcmd.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 46a2b0e..178bd73 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1300,6 +1300,46 @@ signal_command (char *signum_exp, int from_tty) 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 @@ -3008,7 +3048,24 @@ The SIGNAL argument is processed the same as the handle command.\n\ \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, _("\ |