static char static_progname[256];
#if HAVE_EXECINFO_H
+static int yaz_panic_fd = -1;
-static void yaz_invoke_backtrace(char *buf, int buf_sz)
+static void yaz_invoke_gdb(void)
{
- FILE *file = yaz_log_file();
- int fd = fileno(file);
+ int fd = yaz_panic_fd;
pid_t pid;
int fds[2];
- void *backtrace_info[BACKTRACE_SZ];
- int sz = BACKTRACE_SZ;
-
- write(fd, buf, strlen(buf));
- sz = backtrace(backtrace_info, sz);
- backtrace_symbols_fd(backtrace_info, sz, fd);
-
if (pipe(fds) == -1)
{
const char *cp = "backtrace: pipe failed\n";
}
}
+static void yaz_panic_alarm(int sig)
+{
+ const char *cp = "backtrace: backtrace hangs\n";
+
+ write(yaz_panic_fd, cp, strlen(cp));
+ yaz_invoke_gdb();
+ abort();
+}
+
+static void yaz_invoke_backtrace(void)
+{
+ int fd = yaz_panic_fd;
+ void *backtrace_info[BACKTRACE_SZ];
+ int sz = BACKTRACE_SZ;
+
+ signal(SIGALRM, yaz_panic_alarm);
+ alarm(1);
+ sz = backtrace(backtrace_info, sz);
+ backtrace_symbols_fd(backtrace_info, sz, fd);
+}
+
static void yaz_panic_sig_handler(int sig)
{
char buf[512];
+ FILE *file;
signal(SIGABRT, SIG_DFL);
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGFPE, SIG_DFL);
+ signal(SIGBUS, SIG_DFL);
strcpy(buf, "\nYAZ panic received ");
switch (sig)
{
}
yaz_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1,
" PID=" NMEM_INT_PRINTF "\n", (nmem_int_t) getpid());
- yaz_invoke_backtrace(buf, sizeof buf);
+
+ file = yaz_log_file();
+ /* static variable to be used in the following + handlers */
+ yaz_panic_fd = fileno(file);
+
+ write(yaz_panic_fd, buf, strlen(buf));
+ yaz_invoke_backtrace();
+ yaz_invoke_gdb();
abort();
}
#endif
strncpy(static_progname, progname, sizeof(static_progname) - 1);
static_progname[sizeof(static_progname) - 1] = '\0';
#if HAVE_EXECINFO_H
- void *bt[1];
- backtrace(bt, 1);
-
signal(SIGABRT, yaz_panic_sig_handler);
signal(SIGSEGV, yaz_panic_sig_handler);
signal(SIGFPE, yaz_panic_sig_handler);