diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-02-17 16:33:35 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-02-19 15:45:51 +0100 |
commit | b15d422a23a3e4cf1b4195af209211eccdb88d51 (patch) | |
tree | cc7076f950a07749ba9aef323b2e6b514ca5d9f6 /tests/libqtest.c | |
parent | cef60c925c41563721dc73b1ace7b2f399f72a5b (diff) | |
download | qemu-b15d422a23a3e4cf1b4195af209211eccdb88d51.zip qemu-b15d422a23a3e4cf1b4195af209211eccdb88d51.tar.gz qemu-b15d422a23a3e4cf1b4195af209211eccdb88d51.tar.bz2 |
qtest: kill QEMU process on g_assert() failure
The QEMU process stays running if the test case fails. This patch fixes
the leak by installing a SIGABRT signal handler which invokes
qtest_end().
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'tests/libqtest.c')
-rw-r--r-- | tests/libqtest.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/tests/libqtest.c b/tests/libqtest.c index 8b2b2d7..f587d36 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -44,6 +44,7 @@ struct QTestState bool irq_level[MAX_IRQ]; GString *rx; pid_t qemu_pid; /* our child QEMU process */ + struct sigaction sigact_old; /* restored on exit */ }; #define g_assert_no_errno(ret) do { \ @@ -88,6 +89,19 @@ static int socket_accept(int sock) return ret; } +static void kill_qemu(QTestState *s) +{ + if (s->qemu_pid != -1) { + kill(s->qemu_pid, SIGTERM); + waitpid(s->qemu_pid, NULL, 0); + } +} + +static void sigabrt_handler(int signo) +{ + kill_qemu(global_qtest); +} + QTestState *qtest_init(const char *extra_args) { QTestState *s; @@ -96,6 +110,7 @@ QTestState *qtest_init(const char *extra_args) gchar *qmp_socket_path; gchar *command; const char *qemu_binary; + struct sigaction sigact; qemu_binary = getenv("QTEST_QEMU_BINARY"); g_assert(qemu_binary != NULL); @@ -108,6 +123,14 @@ QTestState *qtest_init(const char *extra_args) sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); + /* Catch SIGABRT to clean up on g_assert() failure */ + sigact = (struct sigaction){ + .sa_handler = sigabrt_handler, + .sa_flags = SA_RESETHAND, + }; + sigemptyset(&sigact.sa_mask); + sigaction(SIGABRT, &sigact, &s->sigact_old); + s->qemu_pid = fork(); if (s->qemu_pid == 0) { command = g_strdup_printf("exec %s " @@ -148,13 +171,9 @@ QTestState *qtest_init(const char *extra_args) void qtest_quit(QTestState *s) { - int status; - - if (s->qemu_pid != -1) { - kill(s->qemu_pid, SIGTERM); - waitpid(s->qemu_pid, &status, 0); - } + sigaction(SIGABRT, &s->sigact_old, NULL); + kill_qemu(s); close(s->fd); close(s->qmp_fd); g_string_free(s->rx, true); |