Signed-off-by: Thomas Wood <thomas.w...@intel.com>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to