1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
8 * \brief get information for abnormal terminated, crashes, etc
27 #include <yaz/snprintf.h>
28 #include <yaz/backtrace.h>
32 #include <sys/types.h>
39 #define BACKTRACE_SZ 100
41 static char static_progname[256];
43 static int yaz_panic_fd = -1;
45 static void yaz_invoke_gdb(void)
47 int fd = yaz_panic_fd;
52 const char *cp = "backtrace: pipe failed\n";
53 write(fd, cp, strlen(cp));
57 if (pid == (pid_t) (-1))
59 const char *cp = "backtrace: fork failure\n";
60 write(fd, cp, strlen(cp));
67 const char *cp = "backtrace: could not exec gdb\n";
82 arg[arg_no++] = "/usr/bin/gdb";
84 arg[arg_no++] = "-batch";
85 arg[arg_no++] = "-ex";
86 arg[arg_no++] = "info threads";
87 arg[arg_no++] = "-ex";
88 arg[arg_no++] = "thread apply all bt";
89 arg[arg_no++] = static_progname;
90 sprintf(pidstr, NMEM_INT_PRINTF, (nmem_int_t) getppid());
91 arg[arg_no++] = pidstr;
94 write(2, cp, strlen(cp)); /* exec failure if we make it this far */
102 write(fds[1], "quit\n", 5);
106 pid_t s = waitpid(pid, &status, WNOHANG);
116 write(fds[1], "quit\n", 5);
124 static void yaz_panic_alarm(int sig)
126 const char *cp = "backtrace: backtrace hangs\n";
128 write(yaz_panic_fd, cp, strlen(cp));
133 static void yaz_invoke_backtrace(void)
135 int fd = yaz_panic_fd;
136 void *backtrace_info[BACKTRACE_SZ];
137 int sz = BACKTRACE_SZ;
139 signal(SIGALRM, yaz_panic_alarm);
141 sz = backtrace(backtrace_info, sz);
142 backtrace_symbols_fd(backtrace_info, sz, fd);
145 static void yaz_panic_sig_handler(int sig)
150 signal(SIGABRT, SIG_DFL);
151 signal(SIGSEGV, SIG_DFL);
152 signal(SIGFPE, SIG_DFL);
153 signal(SIGBUS, SIG_DFL);
154 strcpy(buf, "\nYAZ panic received ");
158 strcat(buf, "SIGSEGV");
161 strcat(buf, "SIGABRT");
164 strcat(buf, "SIGFPE");
167 strcat(buf, "SIGBUS");
170 yaz_snprintf(buf + strlen(buf), sizeof buf, "signo=%d", sig);
173 yaz_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1,
174 " PID=" NMEM_INT_PRINTF "\n", (nmem_int_t) getpid());
176 file = yaz_log_file();
177 /* static variable to be used in the following + handlers */
178 yaz_panic_fd = fileno(file);
180 write(yaz_panic_fd, buf, strlen(buf));
181 yaz_invoke_backtrace();
187 void yaz_enable_panic_backtrace(const char *progname)
189 strncpy(static_progname, progname, sizeof(static_progname) - 1);
190 static_progname[sizeof(static_progname) - 1] = '\0';
192 signal(SIGABRT, yaz_panic_sig_handler);
193 signal(SIGSEGV, yaz_panic_sig_handler);
194 signal(SIGFPE, yaz_panic_sig_handler);
195 signal(SIGBUS, yaz_panic_sig_handler);
202 * c-file-style: "Stroustrup"
203 * indent-tabs-mode: nil
205 * vim: shiftwidth=4 tabstop=8 expandtab