diff --git a/.gitmodules b/.gitmodules index de846818..d5d62523 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "dbus/jack_control"] path = dbus/jack_control url = ../jack_control +[submodule "siginfo"] + path = siginfo + url = ../siginfo diff --git a/dbus/jackdbus.c b/dbus/jackdbus.c index 60b2f436..c85ae3a1 100644 --- a/dbus/jackdbus.c +++ b/dbus/jackdbus.c @@ -42,7 +42,9 @@ #include "jack/jack.h" #include "jack/jslist.h" #include "jack/control.h" -#include "sigsegv.h" +#if SIGINFO_ENABLED +#include "../siginfo/siginfo.h" +#endif static char * g_log_filename; static ino_t g_log_file_ino; @@ -896,8 +898,10 @@ main (int argc, char **argv) jack_set_error_function(jack_dbus_error_callback); jack_set_info_function(jack_dbus_info_callback); - /* setup our SIGSEGV magic that prints nice stack in our logfile */ - setup_sigsegv(); +#if SIGINFO_ENABLED + /* setup our SIGSEGV magic that prints nice stack in our logfile */ + setup_siginfo(); +#endif jack_info("------------------"); jack_info("jackdbus version %s built from %s on %s", JACK_VERSION, GIT_VERSION, timestamp_str); diff --git a/dbus/siginfo.c b/dbus/siginfo.c new file mode 100644 index 00000000..aab1c808 --- /dev/null +++ b/dbus/siginfo.c @@ -0,0 +1,5 @@ +/* -*- Mode: C ; c-basic-offset: 2 -*- */ + +#include +#define siginfo_log jack_error +#include "../siginfo/siginfo.c" diff --git a/dbus/sigsegv.c b/dbus/sigsegv.c deleted file mode 100644 index 10ddd0ac..00000000 --- a/dbus/sigsegv.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * This source file is used to print out a stack-trace when your program - * segfaults. It is relatively reliable and spot-on accurate. - * - * This code is in the public domain. Use it as you see fit, some credit - * would be appreciated, but is not a prerequisite for usage. Feedback - * on it's use would encourage further development and maintenance. - * - * Author: Jaco Kroon - * - * Copyright (C) 2005 - 2008 Jaco Kroon - */ - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -//#define NO_CPP_DEMANGLE -#define SIGSEGV_NO_AUTO_INIT - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#ifdef HAVE_EXECINFO_H -# include -#endif -#include -#ifndef NO_CPP_DEMANGLE -char * __cxa_demangle(const char * __mangled_name, char * __output_buffer, size_t * __length, int * __status); -#endif - -#include "jack/control.h" - -#if defined(REG_RIP) -# define SIGSEGV_STACK_IA64 -# define REGFORMAT "%016lx" -#elif defined(REG_EIP) -# define SIGSEGV_STACK_X86 -# define REGFORMAT "%08x" -#else -# define SIGSEGV_STACK_GENERIC -# define REGFORMAT "%x" -#endif - -#ifdef __APPLE__ - -// TODO : does not compile yet on OSX -static void signal_segv(int signum, siginfo_t* info, void*ptr) -{} - -#else - -#include - -static void signal_segv(int signum, siginfo_t* info, void*ptr) { - static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"}; - - const char *si_code_str; - ucontext_t *ucontext = (ucontext_t*)ptr; - -#if (defined(HAVE_UCONTEXT) && defined(HAVE_NGREG)) || defined(HAVE_EXECINFO_H) - size_t i; -#endif -#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) - int f = 0; - Dl_info dlinfo; - void **bp = 0; - void *ip = 0; -#else - void *bt[20]; - char **strings; - size_t sz; -#endif - - if (signum == SIGSEGV) - { - jack_error("Segmentation Fault!"); - } - else if (signum == SIGABRT) - { - jack_error("Abort!"); - } - else if (signum == SIGILL) - { - jack_error("Illegal instruction!"); - } - else if (signum == SIGFPE) - { - jack_error("Floating point exception!"); - } - else - { - jack_error("Unknown bad signal caught!"); - } - - if (info->si_code >= 0 && info->si_code < 3) - si_code_str = si_codes[info->si_code]; - else - si_code_str = "unknown"; - - jack_error("info.si_signo = %d", signum); - jack_error("info.si_errno = %d", info->si_errno); - jack_error("info.si_code = %d (%s)", info->si_code, si_code_str); - jack_error("info.si_addr = %p", info->si_addr); -#if defined(HAVE_UCONTEXT) && defined(HAVE_NGREG) - for(i = 0; i < NGREG; i++) - jack_error("reg[%02d] = 0x" REGFORMAT, i, -#if defined(HAVE_UCONTEXT_GP_REGS) - ucontext->uc_mcontext.gp_regs[i] -#elif defined(HAVE_UCONTEXT_UC_REGS) - ucontext->uc_mcontext.uc_regs[i] -#elif defined(HAVE_UCONTEXT_MC_GREGS) - ucontext->uc_mcontext.mc_gregs[i] -#elif defined(HAVE_UCONTEXT_GREGS) - ucontext->uc_mcontext.gregs[i] -#endif - ); -#endif /* defined(HAVE_UCONTEXT) && defined(HAVE_NGREG) */ - -#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64) -# if defined(SIGSEGV_STACK_IA64) - ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP]; - bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP]; -# elif defined(SIGSEGV_STACK_X86) - ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP]; - bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP]; -# endif - - jack_error("Stack trace:"); - while(bp && ip) { - if(!dladdr(ip, &dlinfo)) - break; - - const char *symname = dlinfo.dli_sname; -#ifndef NO_CPP_DEMANGLE - int status; - char *tmp = __cxa_demangle(symname, NULL, 0, &status); - - if(status == 0 && tmp) - symname = tmp; -#endif - - jack_error("% 2d: %p <%s+%u> (%s)", - ++f, - ip, - symname, - (unsigned)(ip - dlinfo.dli_saddr), - dlinfo.dli_fname); - -#ifndef NO_CPP_DEMANGLE - if(tmp) - free(tmp); -#endif - - if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main")) - break; - - ip = bp[1]; - bp = (void**)bp[0]; - } -#else -# ifdef HAVE_EXECINFO_H - jack_error("Stack trace (non-dedicated):"); - sz = backtrace(bt, 20); - strings = backtrace_symbols(bt, sz); - - for(i = 0; i < sz; ++i) - jack_error("%s", strings[i]); -# else - jack_error("Stack trace not available"); -# endif -#endif - jack_error("End of stack trace"); - exit (-1); -} - -#endif - -int setup_sigsegv() { - struct sigaction action; - - memset(&action, 0, sizeof(action)); - action.sa_sigaction = signal_segv; -#ifdef SA_SIGINFO - action.sa_flags = SA_SIGINFO; -#endif - if(sigaction(SIGSEGV, &action, NULL) < 0) { - jack_error("sigaction failed. errno is %d (%s)", errno, strerror(errno)); - return 0; - } - - if(sigaction(SIGILL, &action, NULL) < 0) { - jack_error("sigaction failed. errno is %d (%s)", errno, strerror(errno)); - return 0; - } - - if(sigaction(SIGABRT, &action, NULL) < 0) { - jack_error("sigaction failed. errno is %d (%s)", errno, strerror(errno)); - return 0; - } - - if(sigaction(SIGFPE, &action, NULL) < 0) { - jack_error("sigaction failed. errno is %d (%s)", errno, strerror(errno)); - return 0; - } - - return 1; -} - -#ifndef SIGSEGV_NO_AUTO_INIT -static void __attribute((constructor)) init(void) { - setup_sigsegv(); -} -#endif diff --git a/dbus/sigsegv.h b/dbus/sigsegv.h deleted file mode 100644 index 55b4f214..00000000 --- a/dbus/sigsegv.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SIGSEGV_H__ -#define __SIGSEGV_H__ - -#ifdef __cplusplus -extern "C" -#endif -int setup_sigsegv(); - -#endif diff --git a/dbus/wscript b/dbus/wscript index cc317e66..24a0d4f6 100644 --- a/dbus/wscript +++ b/dbus/wscript @@ -81,7 +81,6 @@ def build(bld): 'xml.c', 'xml_expat.c', 'xml_write_raw.c', - 'sigsegv.c', 'reserve.c', ] obj.use = ['JACKSERVER'] @@ -100,6 +99,10 @@ def build(bld): '../macosx/uptime.c', ] obj.use += ['PTHREAD', 'DL', 'DBUS-1', 'EXPAT'] + if bld.env['BUILD_SIGINFO']: + obj.source += [ + 'siginfo.c', + ] obj.target = 'jackdbus' # process org.jackaudio.service.in -> org.jackaudio.service diff --git a/siginfo b/siginfo new file mode 160000 index 00000000..ba0ec23f --- /dev/null +++ b/siginfo @@ -0,0 +1 @@ +Subproject commit ba0ec23f8d74c749584910e7c30baebcd368f98a diff --git a/wscript b/wscript index eaa16a9f..cbf4f5ec 100644 --- a/wscript +++ b/wscript @@ -67,6 +67,7 @@ def options(opt): help='Target platform for cross-compiling, e.g. cygwin or win32', ) opt.add_option('--debug', action='store_true', default=False, dest='debug', help='Build debuggable binaries') + opt.add_option('--siginfo', action='store_true', default=False, dest='siginfo', help="Log backtrace on fatal signal") #opt.set_auto_options_define('HAVE_%s') #opt.set_auto_options_style('yesno_and_hack') @@ -269,7 +270,10 @@ def configure(conf): flags.add_candcxx('-g') flags.add_link('-g') + conf.env['BUILD_SIGINFO'] = Options.options.siginfo + conf.define('JACK_VERSION', conf.env['JACK_VERSION']) + conf.define('SIGINFO_ENABLED', conf.env['BUILD_SIGINFO']) conf.write_config_header('config.h', remove=False) conf.recurse('dbus') @@ -290,6 +294,7 @@ def configure(conf): conf.msg('Install prefix', conf.env['PREFIX'], color='CYAN') conf.msg('Library directory', conf.all_envs['']['LIBDIR'], color='CYAN') display_feature(conf, 'Build debuggable binaries', conf.env['BUILD_DEBUG']) + display_feature(conf, 'Build with siginfo', conf.env['BUILD_SIGINFO']) tool_flags = [ ('C compiler flags', ['CFLAGS', 'CPPFLAGS']),