blob: faafb5725b74e9e00b4dc0ff69fed1dae2331914 [file] [log] [blame]
Theodore Ts'o9b3018a2011-08-11 14:56:49 -04001/*
2 * sigcatcher.c --- print a backtrace on a SIGSEGV, et. al
3 *
4 * Copyright (C) 2011 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
10 */
11
Theodore Ts'od1154eb2011-09-18 17:34:37 -040012#include "config.h"
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040013#include <stdio.h>
14#include <stdlib.h>
15#include <signal.h>
16#include <string.h>
17#ifdef HAVE_EXECINFO_H
18#include <execinfo.h>
19#endif
20
21#include "e2fsck.h"
22
23struct str_table {
24 int num;
25 const char *name;
26};
27
28#define DEFINE_ENTRY(SYM) { SYM, #SYM },
29#define END_TABLE { 0, 0 }
30
31static struct str_table sig_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040032#ifdef SIGHUP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040033 DEFINE_ENTRY(SIGHUP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040034#endif
35#ifdef SIGINT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040036 DEFINE_ENTRY(SIGINT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040037#endif
38#ifdef SIGQUIT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040039 DEFINE_ENTRY(SIGQUIT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040040#endif
41#ifdef SIGILL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040042 DEFINE_ENTRY(SIGILL)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040043#endif
44#ifdef SIGTRAP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040045 DEFINE_ENTRY(SIGTRAP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040046#endif
47#ifdef SIGABRT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040048 DEFINE_ENTRY(SIGABRT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040049#endif
50#ifdef SIGIOT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040051 DEFINE_ENTRY(SIGIOT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040052#endif
53#ifdef SIGBUS
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040054 DEFINE_ENTRY(SIGBUS)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040055#endif
56#ifdef SIGFPE
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040057 DEFINE_ENTRY(SIGFPE)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040058#endif
59#ifdef SIGKILL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040060 DEFINE_ENTRY(SIGKILL)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040061#endif
62#ifdef SIGUSR1
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040063 DEFINE_ENTRY(SIGUSR1)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040064#endif
65#ifdef SIGSEGV
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040066 DEFINE_ENTRY(SIGSEGV)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040067#endif
68#ifdef SIGUSR2
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040069 DEFINE_ENTRY(SIGUSR2)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040070#endif
71#ifdef SIGPIPE
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040072 DEFINE_ENTRY(SIGPIPE)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040073#endif
74#ifdef SIGALRM
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040075 DEFINE_ENTRY(SIGALRM)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040076#endif
77#ifdef SIGTERM
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040078 DEFINE_ENTRY(SIGTERM)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040079#endif
80#ifdef SIGSTKFLT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040081 DEFINE_ENTRY(SIGSTKFLT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040082#endif
83#ifdef SIGCHLD
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040084 DEFINE_ENTRY(SIGCHLD)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040085#endif
86#ifdef SIGCONT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040087 DEFINE_ENTRY(SIGCONT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040088#endif
89#ifdef SIGSTOP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040090 DEFINE_ENTRY(SIGSTOP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040091#endif
92#ifdef SIGTSTP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040093 DEFINE_ENTRY(SIGTSTP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040094#endif
95#ifdef SIGTTIN
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040096 DEFINE_ENTRY(SIGTTIN)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -040097#endif
98#ifdef SIGTTOU
Theodore Ts'o9b3018a2011-08-11 14:56:49 -040099 DEFINE_ENTRY(SIGTTOU)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400100#endif
101#ifdef SIGURG
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400102 DEFINE_ENTRY(SIGURG)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400103#endif
104#ifdef SIGXCPU
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400105 DEFINE_ENTRY(SIGXCPU)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400106#endif
107#ifdef SIGXFSZ
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400108 DEFINE_ENTRY(SIGXFSZ)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400109#endif
110#ifdef SIGVTALRM
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400111 DEFINE_ENTRY(SIGVTALRM)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400112#endif
113#ifdef SIGPROF
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400114 DEFINE_ENTRY(SIGPROF)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400115#endif
116#ifdef SIGWINCH
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400117 DEFINE_ENTRY(SIGWINCH)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400118#endif
119#ifdef SIGIO
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400120 DEFINE_ENTRY(SIGIO)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400121#endif
122#ifdef SIGPOLL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400123 DEFINE_ENTRY(SIGPOLL)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400124#endif
125#ifdef SIGPWR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400126 DEFINE_ENTRY(SIGPWR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400127#endif
128#ifdef SIGSYS
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400129 DEFINE_ENTRY(SIGSYS)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400130#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400131 END_TABLE
132};
133
134static struct str_table generic_code_table[] = {
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400135#ifdef SI_ASYNCNL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400136 DEFINE_ENTRY(SI_ASYNCNL)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400137#endif
138#ifdef SI_TKILL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400139 DEFINE_ENTRY(SI_TKILL)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400140#endif
141#ifdef SI_SIGIO
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400142 DEFINE_ENTRY(SI_SIGIO)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400143#endif
144#ifdef SI_ASYNCIO
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400145 DEFINE_ENTRY(SI_ASYNCIO)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400146#endif
147#ifdef SI_MESGQ
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400148 DEFINE_ENTRY(SI_MESGQ)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400149#endif
150#ifdef SI_TIMER
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400151 DEFINE_ENTRY(SI_TIMER)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400152#endif
153#ifdef SI_QUEUE
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400154 DEFINE_ENTRY(SI_QUEUE)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400155#endif
156#ifdef SI_USER
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400157 DEFINE_ENTRY(SI_USER)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400158#endif
159#ifdef SI_KERNEL
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400160 DEFINE_ENTRY(SI_KERNEL)
Theodore Ts'o1c5ffb62011-10-04 10:36:47 -0400161#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400162 END_TABLE
163};
164
165static struct str_table sigill_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400166#ifdef ILL_ILLOPC
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400167 DEFINE_ENTRY(ILL_ILLOPC)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400168#endif
169#ifdef ILL_ILLOPN
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400170 DEFINE_ENTRY(ILL_ILLOPN)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400171#endif
172#ifdef ILL_ILLADR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400173 DEFINE_ENTRY(ILL_ILLADR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400174#endif
175#ifdef ILL_ILLTRP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400176 DEFINE_ENTRY(ILL_ILLTRP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400177#endif
178#ifdef ILL_PRVOPC
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400179 DEFINE_ENTRY(ILL_PRVOPC)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400180#endif
181#ifdef ILL_PRVREG
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400182 DEFINE_ENTRY(ILL_PRVREG)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400183#endif
184#ifdef ILL_COPROC
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400185 DEFINE_ENTRY(ILL_COPROC)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400186#endif
187#ifdef ILL_BADSTK
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400188 DEFINE_ENTRY(ILL_BADSTK)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400189#endif
190#ifdef BUS_ADRALN
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400191 DEFINE_ENTRY(BUS_ADRALN)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400192#endif
193#ifdef BUS_ADRERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400194 DEFINE_ENTRY(BUS_ADRERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400195#endif
196#ifdef BUS_OBJERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400197 DEFINE_ENTRY(BUS_OBJERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400198#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400199 END_TABLE
200};
201
202static struct str_table sigfpe_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400203#ifdef FPE_INTDIV
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400204 DEFINE_ENTRY(FPE_INTDIV)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400205#endif
206#ifdef FPE_INTOVF
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400207 DEFINE_ENTRY(FPE_INTOVF)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400208#endif
209#ifdef FPE_FLTDIV
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400210 DEFINE_ENTRY(FPE_FLTDIV)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400211#endif
212#ifdef FPE_FLTOVF
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400213 DEFINE_ENTRY(FPE_FLTOVF)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400214#endif
215#ifdef FPE_FLTUND
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400216 DEFINE_ENTRY(FPE_FLTUND)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400217#endif
218#ifdef FPE_FLTRES
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400219 DEFINE_ENTRY(FPE_FLTRES)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400220#endif
221#ifdef FPE_FLTINV
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400222 DEFINE_ENTRY(FPE_FLTINV)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400223#endif
224#ifdef FPE_FLTSUB
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400225 DEFINE_ENTRY(FPE_FLTSUB)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400226#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400227 END_TABLE
228};
229
230static struct str_table sigsegv_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400231#ifdef SEGV_MAPERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400232 DEFINE_ENTRY(SEGV_MAPERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400233#endif
234#ifdef SEGV_ACCERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400235 DEFINE_ENTRY(SEGV_ACCERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400236#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400237 END_TABLE
238};
239
240
241static struct str_table sigbus_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400242#ifdef BUS_ADRALN
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400243 DEFINE_ENTRY(BUS_ADRALN)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400244#endif
245#ifdef BUS_ADRERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400246 DEFINE_ENTRY(BUS_ADRERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400247#endif
248#ifdef BUS_OBJERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400249 DEFINE_ENTRY(BUS_OBJERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400250#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400251 END_TABLE
252};
253
Andreas Dilger00eb0ee2012-11-29 05:47:53 -0700254#if 0 /* should this be hooked in somewhere? */
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400255static struct str_table sigstrap_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400256#ifdef TRAP_BRKPT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400257 DEFINE_ENTRY(TRAP_BRKPT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400258#endif
259#ifdef TRAP_TRACE
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400260 DEFINE_ENTRY(TRAP_TRACE)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400261#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400262 END_TABLE
263};
Andreas Dilger00eb0ee2012-11-29 05:47:53 -0700264#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400265
266static struct str_table sigcld_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400267#ifdef CLD_EXITED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400268 DEFINE_ENTRY(CLD_EXITED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400269#endif
270#ifdef CLD_KILLED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400271 DEFINE_ENTRY(CLD_KILLED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400272#endif
273#ifdef CLD_DUMPED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400274 DEFINE_ENTRY(CLD_DUMPED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400275#endif
276#ifdef CLD_TRAPPED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400277 DEFINE_ENTRY(CLD_TRAPPED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400278#endif
279#ifdef CLD_STOPPED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400280 DEFINE_ENTRY(CLD_STOPPED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400281#endif
282#ifdef CLD_CONTINUED
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400283 DEFINE_ENTRY(CLD_CONTINUED)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400284#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400285 END_TABLE
286};
287
Andreas Dilger00eb0ee2012-11-29 05:47:53 -0700288#if 0 /* should this be hooked in somewhere? */
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400289static struct str_table sigpoll_code_table[] = {
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400290#ifdef POLL_IN
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400291 DEFINE_ENTRY(POLL_IN)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400292#endif
293#ifdef POLL_OUT
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400294 DEFINE_ENTRY(POLL_OUT)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400295#endif
296#ifdef POLL_MSG
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400297 DEFINE_ENTRY(POLL_MSG)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400298#endif
299#ifdef POLL_ERR
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400300 DEFINE_ENTRY(POLL_ERR)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400301#endif
302#ifdef POLL_PRI
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400303 DEFINE_ENTRY(POLL_PRI)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400304#endif
305#ifdef POLL_HUP
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400306 DEFINE_ENTRY(POLL_HUP)
Theodore Ts'o0dbb2562011-09-28 22:09:14 -0400307#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400308 END_TABLE
309};
Andreas Dilger00eb0ee2012-11-29 05:47:53 -0700310#endif
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400311
312static const char *lookup_table(int num, struct str_table *table)
313{
314 struct str_table *p;
315
316 for (p=table; p->name; p++)
317 if (num == p->num)
318 return(p->name);
319 return NULL;
320}
321
322static const char *lookup_table_fallback(int num, struct str_table *table)
323{
324 static char buf[32];
325 const char *ret = lookup_table(num, table);
326
327 if (ret)
328 return ret;
329 snprintf(buf, sizeof(buf), "%d", num);
330 buf[sizeof(buf)-1] = 0;
331 return buf;
332}
333
334static void die_signal_handler(int signum, siginfo_t *siginfo, void *context)
335{
336 void *stack_syms[32];
337 int frames;
338 const char *cp;
339
340 fprintf(stderr, "Signal (%d) %s ", signum,
341 lookup_table_fallback(signum, sig_table));
342 if (siginfo->si_code == SI_USER)
343 fprintf(stderr, "(sent from pid %u) ", siginfo->si_pid);
344 cp = lookup_table(siginfo->si_code, generic_code_table);
345 if (cp)
346 fprintf(stderr, "si_code=%s ", cp);
347 else if (signum == SIGILL)
348 fprintf(stderr, "si_code=%s ",
349 lookup_table_fallback(siginfo->si_code,
350 sigill_code_table));
351 else if (signum == SIGFPE)
352 fprintf(stderr, "si_code=%s ",
353 lookup_table_fallback(siginfo->si_code,
354 sigfpe_code_table));
355 else if (signum == SIGSEGV)
356 fprintf(stderr, "si_code=%s ",
357 lookup_table_fallback(siginfo->si_code,
358 sigsegv_code_table));
359 else if (signum == SIGBUS)
360 fprintf(stderr, "si_code=%s ",
361 lookup_table_fallback(siginfo->si_code,
362 sigbus_code_table));
Theodore Ts'o048c0e42011-10-05 14:47:09 -0400363 else if (signum == SIGCHLD)
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400364 fprintf(stderr, "si_code=%s ",
365 lookup_table_fallback(siginfo->si_code,
366 sigcld_code_table));
367 else
368 fprintf(stderr, "si code=%d ", siginfo->si_code);
369 if ((siginfo->si_code != SI_USER) &&
370 (signum == SIGILL || signum == SIGFPE ||
371 signum == SIGSEGV || signum == SIGBUS))
372 fprintf(stderr, "fault addr=%p", siginfo->si_addr);
373 fprintf(stderr, "\n");
374
375#ifdef HAVE_BACKTRACE
376 frames = backtrace(stack_syms, 32);
377 backtrace_symbols_fd(stack_syms, frames, 2);
378#endif
379 exit(FSCK_ERROR);
380}
381
382void sigcatcher_setup(void)
383{
384 struct sigaction sa;
385
Theodore Ts'odd62d852011-09-03 09:43:50 -0400386 memset(&sa, 0, sizeof(struct sigaction));
Theodore Ts'o9b3018a2011-08-11 14:56:49 -0400387 sa.sa_sigaction = die_signal_handler;
388 sa.sa_flags = SA_SIGINFO;
389
390 sigaction(SIGFPE, &sa, 0);
391 sigaction(SIGILL, &sa, 0);
392 sigaction(SIGBUS, &sa, 0);
393 sigaction(SIGSEGV, &sa, 0);
394}
395
396
397#ifdef DEBUG
398#include <getopt.h>
399
400void usage(void)
401{
402 fprintf(stderr, "tst_sigcatcher: [-akfn]\n");
403 exit(1);
404}
405
406int main(int argc, char** argv)
407{
408 struct sigaction sa;
409 char *p = 0;
410 int i, c;
411 volatile x=0;
412
413 memset(&sa, 0, sizeof(struct sigaction));
414 sa.sa_sigaction = die_signal_handler;
415 sa.sa_flags = SA_SIGINFO;
416 for (i=1; i < 31; i++)
417 sigaction(i, &sa, 0);
418
419 while ((c = getopt (argc, argv, "afkn")) != EOF)
420 switch (c) {
421 case 'a':
422 abort();
423 break;
424 case 'f':
425 printf("%d\n", 42/x);
426 case 'k':
427 kill(getpid(), SIGTERM);
428 break;
429 case 'n':
430 *p = 42;
431 default:
432 usage ();
433 }
434
435 printf("Sleeping for 10 seconds, send kill signal to pid %u...\n",
436 getpid());
437 fflush(stdout);
438 sleep(10);
439 exit(0);
440}
441#endif