From patchwork Tue Aug 23 08:38:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marius Vlad X-Patchwork-Id: 9295189 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E9E3260757 for ; Tue, 23 Aug 2016 08:38:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D905B28AF2 for ; Tue, 23 Aug 2016 08:38:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9BD428B34; Tue, 23 Aug 2016 08:38:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 60C3028AF2 for ; Tue, 23 Aug 2016 08:38:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4F11F6E5CC; Tue, 23 Aug 2016 08:38:54 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id CA9606E5CC for ; Tue, 23 Aug 2016 08:38:52 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP; 23 Aug 2016 01:38:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.28,565,1464678000"; d="scan'208"; a="1045764692" Received: from mcvlad-wk.rb.intel.com ([10.237.105.57]) by fmsmga002.fm.intel.com with ESMTP; 23 Aug 2016 01:38:51 -0700 From: Marius Vlad To: intel-gfx@lists.freedesktop.org Date: Tue, 23 Aug 2016 11:38:43 +0300 Message-Id: <1471941523-18730-1-git-send-email-marius.c.vlad@intel.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <20160820182313.GH16497@nuc-i3427.alporthouse.com> References: <20160820182313.GH16497@nuc-i3427.alporthouse.com> Subject: [Intel-gfx] [PATCH i-g-t v2] lib/igt_core: Print stacktrace when receiving one of the crash signals. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP While at it add SIGFPE as a crash signal. v2: Added some helpers to avoid printf() inside a signal handler. (Chris Wilson) Signed-off-by: Marius Vlad CC: Chris Wilson --- lib/igt_core.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 2 deletions(-) diff --git a/lib/igt_core.c b/lib/igt_core.c index 801f02f..472d01a 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -1098,6 +1098,165 @@ static void print_backtrace(void) (unsigned int) off); } } + +static const char hex[] = "0123456789abcdef"; +typedef void (*print_func)(int ch); + +static void +xputch(int c) +{ + igt_assert_eq(write(STDERR_FILENO, (const void *) &c, 1), 1); +} + +static void +printnum(print_func putch, unsigned long long num, unsigned base) +{ + /* recursively print all preceding digits */ + if (num >= base) { + printnum(putch, num / base, base); + } + + /* print the least significant digit */ + putch(hex[num % base]); +} + +static size_t +xstrlcpy(char *dst, const char *src, size_t size) +{ + char *dst_in; + + dst_in = dst; + if (size > 0) { + while (--size > 0 && *src != '\0') + *dst++ = *src++; + *dst = '\0'; + } + + return dst - dst_in; +} + +static void +xprintfmt(print_func putch, const char *fmt, va_list ap) +{ + const char *p; + int ch, base; + unsigned long long num; + + while (1) { + while ((ch = *(unsigned char *) fmt++) != '%') { + if (ch == '\0') { + return; + } + putch(ch); + } + + ch = *(unsigned char *) fmt++; + switch (ch) { + /* character */ + case 'c': + putch(va_arg(ap, int)); + break; + /* string */ + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + p = "(null)"; + } + + for (; (ch = *p++) != '\0';) { + if (ch < ' ' || ch > '~') { + putch('?'); + } else { + putch(ch); + } + } + break; + /* (signed) decimal */ + case 'd': + num = va_arg(ap, int); + if ((long long) num < 0) { + putch('-'); + num = -(long long) num; + } + base = 10; + goto number; + /* unsigned decimal */ + case 'u': + num = va_arg(ap, unsigned int); + base = 10; + goto number; + /* (unsigned) hexadecimal */ + case 'x': + num = va_arg(ap, unsigned int); + base = 16; +number: + printnum(putch, num, base); + break; + + /* The following are not implemented */ + + /* width field */ + case '1': case '2': + case '3': case '4': + case '5': case '6': + case '7': case '8': + case '9': + case '.': case '#': + /* long */ + case 'l': + /* octal */ + case 'o': + /* pointer */ + case 'p': + /* float */ + case 'f': + abort(); + /* escaped '%' character */ + case '%': + putch(ch); + break; + /* unrecognized escape sequence - just print it literally */ + default: + putch('%'); + for (fmt--; fmt[-1] != '%'; fmt--) + ; /* do nothing */ + break; + } + } +} + +/* async-safe printf */ +static void +xprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xprintfmt((void *) xputch, fmt, ap); + va_end(ap); +} + +static void print_backtrace_sig_safe(void) +{ + unw_cursor_t cursor; + unw_context_t uc; + int stack_num = 0; + + igt_assert_eq(write(STDERR_FILENO, "Stack trace: \n", 15), 15); + + unw_getcontext(&uc); + unw_init_local(&cursor, &uc); + while (unw_step(&cursor) > 0) { + char name[255]; + unw_word_t off; + + if (unw_get_proc_name(&cursor, name, 255, &off) < 0) + xstrlcpy(name, "", 9); + + xprintf(" #%d [%s+0x%x]\n", stack_num++, name, + (unsigned int) off); + + } +} #endif void __igt_fail_assert(const char *domain, const char *file, const int line, @@ -1482,7 +1641,8 @@ static bool exit_handler_disabled; #define SILENT(x) { x, NULL, 0 } static const struct { int number; const char *name; size_t name_len; } handled_signals[] = { SILENT(SIGINT), SILENT(SIGHUP), SILENT(SIGTERM), SILENT(SIGQUIT), - SILENT(SIGPIPE), SIGDEF(SIGABRT), SIGDEF(SIGSEGV), SIGDEF(SIGBUS) }; + SILENT(SIGPIPE), SIGDEF(SIGABRT), SIGDEF(SIGSEGV), SIGDEF(SIGBUS), + SIGDEF(SIGFPE) }; #undef SILENT #undef SIGDEF @@ -1542,6 +1702,7 @@ static bool crash_signal(int sig) switch (sig) { case SIGILL: case SIGBUS: + case SIGFPE: case SIGSEGV: return true; default: @@ -1571,7 +1732,7 @@ static void fatal_sig_handler(int sig) igt_exitcode = 128 + sig; failed_one = true; - + print_backtrace_sig_safe(); exit_subtest("CRASH"); } break;