Max Reitz <mre...@redhat.com> writes: > abort() has the sometimes undesirable side-effect of generating a core > dump. If that is not needed, SIGKILL has the same effect of abruptly > crash qemu; without a core dump. > > Therefore, this patch allows to use the qemu-io abort command to raise > any signal. > > Signed-off-by: Max Reitz <mre...@redhat.com> > --- > qemu-io-cmds.c | 59 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 56 insertions(+), 3 deletions(-) > > diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c > index d94fb1e..5d39cf4 100644 > --- a/qemu-io-cmds.c > +++ b/qemu-io-cmds.c > @@ -2036,18 +2036,71 @@ static const cmdinfo_t wait_break_cmd = { > .oneline = "waits for the suspension of a request", > }; > > -static int abort_f(BlockDriverState *bs, int argc, char **argv) > + > +static void abort_help(void) > { > - abort(); > + printf( > +"\n" > +" simulates a program crash\n" > +"\n" > +" Invokes abort(), or raise(signal) if a signal number is specified.\n" > +" -S, -- number of the signal to raise()\n" > +"\n"); > } > > +static int abort_f(BlockDriverState *bs, int argc, char **argv); > + > static const cmdinfo_t abort_cmd = { > .name = "abort", > .cfunc = abort_f, > + .argmin = 0, > + .argmax = 2, > .flags = CMD_NOFILE_OK, > - .oneline = "simulate a program crash using abort(3)", > + .args = "[-S signal]", > + .oneline = "simulate a program crash", > + .help = abort_help, > };
This overloads the abort command with a kill command. Do we really need a way to send arbitrary signals? If yes, shouldn't we call it "kill" rather than "abort"? I suspect fooling around with signals isn't necessary, and a simple exit(1) would do. > > +static int abort_f(BlockDriverState *bs, int argc, char **argv) > +{ > + int c; > + int sig = -1; > + > + while ((c = getopt(argc, argv, "S:")) != EOF) { > + switch (c) { > + case 'S': > + sig = cvtnum(optarg); > + if (sig < 0) { > + printf("non-numeric signal number argument -- %s\n", > optarg); > + return 0; > + } > + break; > + > + default: > + return qemuio_command_usage(&abort_cmd); > + } > + } > + > + if (optind != argc) { > + return qemuio_command_usage(&abort_cmd); > + } > + > + if (sig < 0) { > + abort(); > + } else { > + /* While abort() does flush all open streams, using raise() to kill > this > + * process does not necessarily. At least stdout and stderr (although > + * the latter should be non-buffered anyway) should be flushed, > though. > + */ > + fflush(stdout); > + fflush(stderr); Without -S, we flush all streams. With -S, we flush only stdout and stderr. The inconsistency is ugly. Could be avoided with fcloseall(), except it's a GNU extension. Or drop the non-signal path entirely, and raise(SIGABRT) instead of abort(). > + > + raise(sig); > + /* raise() may return */ > + return 0; > + } > +} > + > static void sleep_cb(void *opaque) > { > bool *expired = opaque;