@@ -50,6 +50,7 @@
#include <termios.h>
#include <errno.h>
#include <time.h>
+#include <limits.h>
#include "drmtest.h"
#include "intel_chipset.h"
@@ -228,8 +229,16 @@ enum {
OPT_HELP = 'h'
};
+static const char *command_str;
+static int igt_exitcode = IGT_EXIT_SUCCESS;
+
static char* igt_log_domain_filter;
+static struct {
+ char *entries[256];
+ uint8_t start, end;
+} log_buffer;
+
__attribute__((format(printf, 1, 2)))
static void kmsg(const char *format, ...)
#define KERN_EMER "<0>"
@@ -353,6 +362,38 @@ static void low_mem_killer_disable(bool disable)
chmod(adj_fname, buf.st_mode);
}
+static void write_log(void)
+{
+ uint8_t i;
+ int log, pos;
+ char filename[NAME_MAX];
+ const char *ext = ".log";
+
+ /* don't write an empty log */
+ if (log_buffer.start == log_buffer.end)
+ return;
+
+ /* copy the test filename and append ".log" in a signal handler safe
+ * way */
+ for (i = 0; command_str[i] && i < NAME_MAX - 5; i++)
+ filename[i] = command_str[i];
+ pos = i;
+ for (i = 0; pos + i < NAME_MAX; i++) {
+ filename[pos + i] = ext[i];
+ if (ext[i] == '\0')
+ break;
+ }
+
+ log = open(filename, O_CREAT|O_WRONLY);
+ i = log_buffer.start;
+ do {
+ int len = strlen(log_buffer.entries[i]);
+ write(log, log_buffer.entries[i], len);
+ i++;
+ } while (i != log_buffer.start && i != log_buffer.end);
+ close(log);
+}
+
bool igt_exit_called;
static void common_exit_handler(int sig)
{
@@ -361,6 +402,10 @@ 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);
+
+ /* write the log out to a file if the test failed */
+ if (sig || (igt_exitcode != IGT_EXIT_SUCCESS && igt_exitcode != IGT_EXIT_SKIP))
+ write_log();
}
static void print_test_description(void)
@@ -383,8 +428,6 @@ static void print_version(void)
uts.sysname, uts.release, uts.machine);
}
-static const char *command_str;
-
static void print_usage(const char *help_str, bool output_on_stderr)
{
FILE *f = output_on_stderr ? stderr : stdout;
@@ -728,7 +771,6 @@ bool igt_only_list_subtests(void)
static bool skipped_one = false;
static bool succeeded_one = false;
static bool failed_one = false;
-static int igt_exitcode = IGT_EXIT_SUCCESS;
static void exit_subtest(const char *) __attribute__((noreturn));
static void exit_subtest(const char *result)
@@ -1458,21 +1500,28 @@ void igt_log(const char *domain, enum igt_log_level level, const char *format, .
void igt_vlog(const char *domain, enum igt_log_level level, const char *format, va_list args)
{
FILE *file;
+ char *line;
assert(format);
if (list_subtests)
return;
- if (igt_log_level > level)
- return;
+ if (!domain)
+ domain = command_str;
+
+ /* store any log output in ring buffer */
+ free(log_buffer.entries[log_buffer.end]);
+ vasprintf(&line, format, args);
+ asprintf(&log_buffer.entries[log_buffer.end], "(%s:%d) %s",
+ domain, getpid(), line);
+ log_buffer.end++;
+ if (log_buffer.end == log_buffer.start)
+ log_buffer.start++;
if (igt_log_level > level)
return;
- if (!domain)
- domain = command_str;
-
if (igt_log_domain_filter && strcmp(igt_log_domain_filter, domain))
return;
@@ -1483,8 +1532,7 @@ void igt_vlog(const char *domain, enum igt_log_level level, const char *format,
else
file = stdout;
- fprintf(file, "(%s:%d) ", domain, getpid());
- vfprintf(file, format, args);
+ fprintf(file, "(%s:%d) %s", domain, getpid(), line);
}
static void igt_alarm_handler(int signal)
Signed-off-by: Thomas Wood <thomas.wood@intel.com> --- lib/igt_core.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 10 deletions(-)