#include <execinfo.h>
#endif
-#define BACKTRACE_SZ 1000
+#define BACKTRACE_SZ 100
void yaz_invoke_backtrace(char *buf, int buf_sz)
{
backtrace_info[i], backtrace_str[i]);
}
}
-#endif
write(fd, buf, strlen(buf));
+
+ if (backtrace_str)
+ {
+ pid_t pid;
+ const char *cp = "-----------\n";
+ write(fd, cp, strlen(cp));
+
+ pid = fork();
+ if (pid == (pid_t) (-1))
+ { /* error */
+ const char *cp = "backtrace: fork failure";
+ write(fd, cp, strlen(cp));
+ }
+ else if (pid == 0)
+ { /* child */
+ int i;
+ char *arg[BACKTRACE_SZ + 4];
+ int arg_no = 0;
+ char *cp;
+
+ close(0);
+ dup(fd);
+ close(1);
+ dup(fd);
+ if (fd != 2)
+ {
+ close(2);
+ dup(fd);
+ }
+ arg[arg_no++] = "addr2line";
+ arg[arg_no++] = "-paf";
+ arg[arg_no++] = "-e";
+ arg[arg_no++] = backtrace_str[0];
+ cp = strchr(backtrace_str[0], '(');
+ if (cp)
+ *cp = '\0';
+
+ for (i = 1; i < sz; i++)
+ {
+ cp = strchr(backtrace_str[i], '[');
+ if (cp)
+ arg[arg_no++] = cp + 1;
+ }
+ arg[arg_no] = 0;
+ execv("/usr/bin/addr2line", arg);
+ _exit(1);
+ }
+ else
+ { /* parent */
+ int status;
+ waitpid(pid, &status, 0);
+ if (status)
+ {
+ char msg[100];
+ sprintf(msg, "backtrace: exit status=%d\n", status);
+ write(fd, msg, strlen(msg));
+ }
+ }
+ }
+#else
+ strcat(buf, "no backtrace support (execinfo.h not found)\n");
+ write(fd, buf, strlen(buf));
+#endif
}
void yaz_panic_sig_handler(int sig)
void yaz_enable_panic_backtrace(void)
{
+#if HAVE_EXECINFO_H
signal(SIGABRT, yaz_panic_sig_handler);
signal(SIGSEGV, yaz_panic_sig_handler);
signal(SIGFPE, yaz_panic_sig_handler);
signal(SIGBUS, yaz_panic_sig_handler);
+#endif
}
/*