From 994086cfd911e827223a0d889e6c07ebfa875750 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Tue, 7 Nov 2023 02:44:43 +0200 Subject: [PATCH] Replace sigsegv.c with siginfo.c and build it only when explicitly enabled siginfo is disabled by default so building on new CPU architectures does not require adjusting of siginfo.c anymore. When needed, --siginfo can be used as option to ./waf configure to enable the functionality --- .gitmodules | 3 + dbus/jackdbus.c | 10 ++- dbus/siginfo.c | 5 ++ dbus/sigsegv.c | 220 ------------------------------------------------ dbus/sigsegv.h | 9 -- dbus/wscript | 5 +- siginfo | 1 + wscript | 5 ++ 8 files changed, 25 insertions(+), 233 deletions(-) create mode 100644 dbus/siginfo.c delete mode 100644 dbus/sigsegv.c delete mode 100644 dbus/sigsegv.h create mode 160000 siginfo 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']),