[go: up one dir, main page]

File: util_panic.c

package info (click to toggle)
s390-tools 2.35.0-1
  • links: PTS
  • area: main
  • in suites: trixie
  • size: 12,220 kB
  • sloc: ansic: 184,236; sh: 12,152; cpp: 4,954; makefile: 2,763; perl: 2,519; asm: 1,085; python: 697; xml: 29
file content (121 lines) | stat: -rw-r--r-- 3,039 bytes parent folder | download | duplicates (2)
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);
}