Signed-off-by: Thomas Wood <thomas.wood@xxxxxxxxx> --- lib/igt_core.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/lib/igt_core.c b/lib/igt_core.c index d53fabb..c369ed7 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -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) -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx