summaryrefslogtreecommitdiff
path: root/lib/igt_core.c
diff options
context:
space:
mode:
authorArkadiusz Hiler <arkadiusz.hiler@intel.com>2020-02-25 18:55:10 +0200
committerArkadiusz Hiler <arkadiusz.hiler@intel.com>2020-03-23 15:47:34 +0200
commitcf80b710838c2bdb48c629ab85cd295ed74423c6 (patch)
tree9bd4ba75898fdbb743d79de90e1df53a68e0526f /lib/igt_core.c
parentdc8911099bbf2894da2f04a6dcfe0499320666d9 (diff)
lib: Make it possible to abort the whole execution from inside of a test
igt_abort_on_f() is introduced which does very little cleanup and causes a hard exit() of the test binary with a unique exit code (IGT_EXIT_ABORT). The exit code informs the monitoring process that there is a critical issue with the testing environment which may have an impact on the results if testing continues. v2: Add a meta_test Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com> Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'lib/igt_core.c')
-rw-r--r--lib/igt_core.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 2b928f1a..77862498 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -590,6 +590,7 @@ static void ftrace_dump_on_oops(bool enable)
}
bool igt_exit_called;
+bool igt_is_aborting;
static void common_exit_handler(int sig)
{
if (!igt_only_list_subtests()) {
@@ -598,7 +599,7 @@ static void common_exit_handler(int sig)
/* When not killed by a signal check that igt_exit() has been properly
* called. */
- assert(sig != 0 || igt_exit_called);
+ assert(sig != 0 || igt_exit_called || igt_is_aborting);
}
static void print_line_wrapping(const char *indent, const char *text)
@@ -1947,6 +1948,48 @@ void __igt_fail_assert(const char *domain, const char *file, const int line,
igt_fail(IGT_EXIT_FAILURE);
}
+static void kill_children(void)
+{
+ for (int c = 0; c < num_test_children; c++)
+ kill(test_children[c], SIGKILL);
+}
+
+void __igt_abort(const char *domain, const char *file, const int line,
+ const char *func, const char *expression,
+ const char *f, ...)
+{
+ va_list args;
+ int err = errno;
+
+ igt_is_aborting = true;
+
+ igt_log(domain, IGT_LOG_CRITICAL,
+ "Test abort in function %s, file %s:%i:\n", func, file,
+ line);
+ igt_log(domain, IGT_LOG_CRITICAL, "abort condition: %s\n", expression);
+ if (err)
+ igt_log(domain, IGT_LOG_CRITICAL, "Last errno: %i, %s\n", err,
+ strerror(err));
+
+ if (f) {
+ va_start(args, f);
+ igt_vlog(domain, IGT_LOG_CRITICAL, f, args);
+ va_end(args);
+ }
+
+ /* just try our best, we are aborting the execution anyway */
+ kill_children();
+
+ print_backtrace();
+
+ if (running_under_gdb())
+ abort();
+
+ _igt_log_buffer_dump();
+
+ exit(IGT_EXIT_ABORT);
+}
+
/**
* igt_exit:
*
@@ -1996,8 +2039,7 @@ void igt_exit(void)
command_str, igt_exitcode);
igt_debug("Exiting with status code %d\n", igt_exitcode);
- for (int c = 0; c < num_test_children; c++)
- kill(test_children[c], SIGKILL);
+ kill_children();
assert(!num_test_children);
assert(waitpid(-1, &tmp, WNOHANG) == -1 && errno == ECHILD);