1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/*
* util - Utility function library
*
* Collect FFDC data for unexpected errors
*
* Copyright IBM Corp. 2016, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <execinfo.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/time.h>
#include "lib/util_base.h"
#include "lib/util_panic.h"
/*
* Obtain a backtrace and print it to stderr
*
* To get symbols, link the code with "-rdynamic".
*/
static void print_backtrace(void)
{
void *array[256];
size_t i, size;
char **strings;
fprintf(stderr, "Backtrace:\n\n");
size = backtrace(array, ARRAY_SIZE(array));
strings = backtrace_symbols(array, size);
if (strings == NULL) {
fprintf(stderr, " Could not obtain backtrace (ENOMEM)\n");
return;
}
for (i = 0; i < size; i++)
fprintf(stderr, " %s\n", strings[i]);
free(strings);
}
/*
* Check for core ulimit
*/
static void ulimit_core_check(void)
{
struct rlimit limit;
if (getrlimit(RLIMIT_CORE, &limit) != 0)
return;
if (limit.rlim_cur != 0)
return;
fprintf(stderr, "Core dump size is zero. To get a full core dump use 'ulimit -c unlimited'.\n");
}
/*
* Print FFDC data and then abort
*/
static void panic_finish(const char *func, const char *file, int line,
const char *fmt, va_list ap)
{
/* Write panic error string */
fprintf(stderr, "\n");
fprintf(stderr, "Error string:\n");
fprintf(stderr, "\n");
fprintf(stderr, " ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
/* Write file, line number, and function name */
fprintf(stderr, "Location:\n\n");
fprintf(stderr, " %s:%d: %s()\n", file, line, func);
fprintf(stderr, "\n");
/* Print the function backtrace */
print_backtrace();
fprintf(stderr, "\n");
ulimit_core_check();
fprintf(stderr, "----------------------------------------------------------------------->8-----\n");
abort();
}
/*
* Do panic processing if the assumption is not true
*/
void __util_assert(const char *assertion_str,
const char *func, const char *file, int line,
int assumption, const char *fmt, ...)
{
va_list ap;
if (assumption)
return;
va_start(ap, fmt);
fprintf(stderr, "---8<-------------------------------------------------------------------------\n");
fprintf(stderr, "ASSERTION FAILED: The application terminated due to an internal or OS error\n");
fprintf(stderr, "\n");
fprintf(stderr, "The following assumption was *not* true:\n");
fprintf(stderr, "\n");
fprintf(stderr, " %s\n", assertion_str);
panic_finish(func, file, line, fmt, ap);
}
/*
* Do panic processing
*/
void __noreturn __util_panic(const char *func, const char *file, int line,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "---8<-------------------------------------------------------------------------\n");
fprintf(stderr, "PANIC: The application terminated due to an unrecoverable error\n");
panic_finish(func, file, line, fmt, ap);
while(1);
}
|