0001
0002
0003
0004
0005
0006
0007
0008 #define _GNU_SOURCE
0009
0010 #include "test_util.h"
0011
0012 #include <execinfo.h>
0013 #include <sys/syscall.h>
0014
0015 #include "kselftest.h"
0016
0017
0018 static void __attribute__((noinline)) test_dump_stack(void);
0019 static void test_dump_stack(void)
0020 {
0021
0022
0023
0024
0025
0026
0027
0028
0029 size_t i;
0030 size_t n = 20;
0031 void *stack[n];
0032 const char *addr2line = "addr2line -s -e /proc/$PPID/exe -fpai";
0033 const char *pipeline = "|cat -n 1>&2";
0034 char cmd[strlen(addr2line) + strlen(pipeline) +
0035
0036 n * (((sizeof(void *)) * 2) + 1) +
0037
0038 1];
0039 char *c = cmd;
0040
0041 n = backtrace(stack, n);
0042
0043
0044
0045
0046
0047
0048 if (n <= 2) {
0049 fputs(" (stack trace empty)\n", stderr);
0050 return;
0051 }
0052
0053 c += sprintf(c, "%s", addr2line);
0054 for (i = 2; i < n; i++)
0055 c += sprintf(c, " %lx", ((unsigned long) stack[i]) - 1);
0056
0057 c += sprintf(c, "%s", pipeline);
0058 #pragma GCC diagnostic push
0059 #pragma GCC diagnostic ignored "-Wunused-result"
0060 system(cmd);
0061 #pragma GCC diagnostic pop
0062 }
0063
0064 static pid_t _gettid(void)
0065 {
0066 return syscall(SYS_gettid);
0067 }
0068
0069 void __attribute__((noinline))
0070 test_assert(bool exp, const char *exp_str,
0071 const char *file, unsigned int line, const char *fmt, ...)
0072 {
0073 va_list ap;
0074
0075 if (!(exp)) {
0076 va_start(ap, fmt);
0077
0078 fprintf(stderr, "==== Test Assertion Failure ====\n"
0079 " %s:%u: %s\n"
0080 " pid=%d tid=%d errno=%d - %s\n",
0081 file, line, exp_str, getpid(), _gettid(),
0082 errno, strerror(errno));
0083 test_dump_stack();
0084 if (fmt) {
0085 fputs(" ", stderr);
0086 vfprintf(stderr, fmt, ap);
0087 fputs("\n", stderr);
0088 }
0089 va_end(ap);
0090
0091 if (errno == EACCES) {
0092 print_skip("Access denied - Exiting");
0093 exit(KSFT_SKIP);
0094 }
0095 exit(254);
0096 }
0097
0098 return;
0099 }