From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XtD4B-0004BK-U3 for qemu-devel@nongnu.org; Tue, 25 Nov 2014 05:09:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XtD45-00015f-QF for qemu-devel@nongnu.org; Tue, 25 Nov 2014 05:09:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54541) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XtD45-00015Y-Hc for qemu-devel@nongnu.org; Tue, 25 Nov 2014 05:09:45 -0500 From: Max Reitz Date: Tue, 25 Nov 2014 11:09:36 +0100 Message-Id: <1416910178-5088-2-git-send-email-mreitz@redhat.com> In-Reply-To: <1416910178-5088-1-git-send-email-mreitz@redhat.com> References: <1416910178-5088-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH 1/3] qemu-io: Let -c abort raise any signal List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Fam Zheng , =?UTF-8?q?Michael=20M=C3=BCller?= , Mao Chuan Li , Max Reitz , Stefan Hajnoczi 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 --- 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, }; +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); + + raise(sig); + /* raise() may return */ + return 0; + } +} + static void sleep_cb(void *opaque) { bool *expired = opaque; -- 1.9.3