1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004,2005 Voltaire Inc.  All rights reserved.
3219820Sjeff *
4219820Sjeff * This software is available to you under a choice of one of two
5219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
6219820Sjeff * General Public License (GPL) Version 2, available from the file
7219820Sjeff * COPYING in the main directory of this source tree, or the
8219820Sjeff * OpenIB.org BSD license below:
9219820Sjeff *
10219820Sjeff *     Redistribution and use in source and binary forms, with or
11219820Sjeff *     without modification, are permitted provided that the following
12219820Sjeff *     conditions are met:
13219820Sjeff *
14219820Sjeff *      - Redistributions of source code must retain the above
15219820Sjeff *        copyright notice, this list of conditions and the following
16219820Sjeff *        disclaimer.
17219820Sjeff *
18219820Sjeff *      - Redistributions in binary form must reproduce the above
19219820Sjeff *        copyright notice, this list of conditions and the following
20219820Sjeff *        disclaimer in the documentation and/or other materials
21219820Sjeff *        provided with the distribution.
22219820Sjeff *
23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30219820Sjeff * SOFTWARE.
31219820Sjeff *
32219820Sjeff */
33219820Sjeff
34219820Sjeff#define _GNU_SOURCE
35219820Sjeff
36219820Sjeff#if HAVE_CONFIG_H
37219820Sjeff#  include <config.h>
38219820Sjeff#endif /* HAVE_CONFIG_H */
39219820Sjeff
40219820Sjeff#include <inttypes.h>
41219820Sjeff#include <string.h>
42219820Sjeff#include <errno.h>
43219820Sjeff#include <stdio.h>
44219820Sjeff#include <stdlib.h>
45219820Sjeff#include <unistd.h>
46219820Sjeff#include <stdarg.h>
47219820Sjeff#include <sys/types.h>
48219820Sjeff#include <sys/stat.h>
49219820Sjeff#include <fcntl.h>
50219820Sjeff#include <sys/ioctl.h>
51219820Sjeff#include <unistd.h>
52219820Sjeff#include <string.h>
53219820Sjeff#include <endian.h>
54219820Sjeff#include <byteswap.h>
55219820Sjeff#include <sys/poll.h>
56219820Sjeff#include <syslog.h>
57219820Sjeff#include <time.h>
58219820Sjeff#include <signal.h>
59219820Sjeff
60219820Sjeff#include "common.h"
61219820Sjeff
62219820Sjeffstatic int loop_on_panic;
63219820Sjeff
64219820Sjeffvoid
65219820Sjeffstack_dump(void)
66219820Sjeff{
67219820Sjeff	if (!__builtin_frame_address(1))
68219820Sjeff		return
69219820Sjeff	syslog(LOG_ALERT, "#1 %p\n", __builtin_return_address(1));
70219820Sjeff
71219820Sjeff	if (!__builtin_frame_address(2))
72219820Sjeff		return
73219820Sjeff	syslog(LOG_ALERT, "#2 %p\n", __builtin_return_address(2));
74219820Sjeff
75219820Sjeff	if (!__builtin_frame_address(3))
76219820Sjeff		return
77219820Sjeff	syslog(LOG_ALERT, "#3 %p\n", __builtin_return_address(3));
78219820Sjeff
79219820Sjeff	if (!__builtin_frame_address(4))
80219820Sjeff		return
81219820Sjeff	syslog(LOG_ALERT, "#4 %p\n", __builtin_return_address(4));
82219820Sjeff
83219820Sjeff	if (!__builtin_frame_address(5))
84219820Sjeff		return
85219820Sjeff	syslog(LOG_ALERT, "#5 %p\n", __builtin_return_address(5));
86219820Sjeff
87219820Sjeff	if (!__builtin_frame_address(6))
88219820Sjeff		return
89219820Sjeff	syslog(LOG_ALERT, "#6 %p\n", __builtin_return_address(6));
90219820Sjeff
91219820Sjeff	if (!__builtin_frame_address(7))
92219820Sjeff		return
93219820Sjeff	syslog(LOG_ALERT, "#7 %p\n", __builtin_return_address(7));
94219820Sjeff
95219820Sjeff	if (!__builtin_frame_address(8))
96219820Sjeff		return
97219820Sjeff	syslog(LOG_ALERT, "#8 %p\n", __builtin_return_address(8));
98219820Sjeff
99219820Sjeff	if (!__builtin_frame_address(9))
100219820Sjeff		return
101219820Sjeff	syslog(LOG_ALERT, "#9 %p\n", __builtin_return_address(9));
102219820Sjeff
103219820Sjeff	if (!__builtin_frame_address(10))
104219820Sjeff		return
105219820Sjeff	syslog(LOG_ALERT, "#10 %p\n", __builtin_return_address(10));
106219820Sjeff
107219820Sjeff	if (!__builtin_frame_address(11))
108219820Sjeff		return
109219820Sjeff	syslog(LOG_ALERT, "#11 %p\n", __builtin_return_address(11));
110219820Sjeff
111219820Sjeff	if (!__builtin_frame_address(12))
112219820Sjeff		return
113219820Sjeff	syslog(LOG_ALERT, "#12 %p\n", __builtin_return_address(12));
114219820Sjeff
115219820Sjeff	if (!__builtin_frame_address(13))
116219820Sjeff		return
117219820Sjeff	syslog(LOG_ALERT, "#13 %p\n", __builtin_return_address(13));
118219820Sjeff
119219820Sjeff	if (!__builtin_frame_address(14))
120219820Sjeff		return
121219820Sjeff	syslog(LOG_ALERT, "#14 %p\n", __builtin_return_address(14));
122219820Sjeff
123219820Sjeff	if (!__builtin_frame_address(15))
124219820Sjeff		return
125219820Sjeff	syslog(LOG_ALERT, "#15 %p\n", __builtin_return_address(15));
126219820Sjeff
127219820Sjeff	if (!__builtin_frame_address(16))
128219820Sjeff		return
129219820Sjeff	syslog(LOG_ALERT, "#16 %p\n", __builtin_return_address(16));
130219820Sjeff
131219820Sjeff	if (!__builtin_frame_address(17))
132219820Sjeff		return
133219820Sjeff	syslog(LOG_ALERT, "#17 %p\n", __builtin_return_address(17));
134219820Sjeff
135219820Sjeff	if (!__builtin_frame_address(18))
136219820Sjeff		return
137219820Sjeff	syslog(LOG_ALERT, "#18 %p\n", __builtin_return_address(18));
138219820Sjeff}
139219820Sjeff
140219820Sjeffstatic void
141219820Sjeffhandler(int x)
142219820Sjeff{
143219820Sjeff	static int in;
144219820Sjeff	time_t  tm;
145219820Sjeff
146219820Sjeff	if (!in) {
147219820Sjeff		in++;
148219820Sjeff
149219820Sjeff		syslog(LOG_ALERT, "*** exception handler: died with signal %d", x);
150219820Sjeff		stack_dump();
151219820Sjeff
152219820Sjeff		fflush(NULL);
153219820Sjeff
154219820Sjeff		tm = time(0);
155219820Sjeff		fprintf(stderr, "%s *** exception handler: died with signal %d pid %d\n",
156219820Sjeff				ctime(&tm), x, getpid());
157219820Sjeff
158219820Sjeff		fflush(NULL);
159219820Sjeff	}
160219820Sjeff
161219820Sjeff	if (loop_on_panic) {
162219820Sjeff		fprintf(stderr, "exception handler: entering tight loop ... pid %d\n",getpid());
163219820Sjeff		for (; ; )
164219820Sjeff			;
165219820Sjeff	}
166219820Sjeff
167219820Sjeff	signal(x, SIG_DFL);
168219820Sjeff}
169219820Sjeff
170219820Sjeffvoid
171219820Sjeffenable_stack_dump(int loop)
172219820Sjeff{
173219820Sjeff	loop_on_panic = loop;
174219820Sjeff	signal(SIGILL, handler);
175219820Sjeff	signal(SIGBUS, handler);
176219820Sjeff	signal(SIGSEGV, handler);
177219820Sjeff	signal(SIGABRT, handler);
178219820Sjeff}
179