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
This commit is contained in:
parent
36bdfb2c65
commit
994086cfd9
|
@ -4,3 +4,6 @@
|
|||
[submodule "dbus/jack_control"]
|
||||
path = dbus/jack_control
|
||||
url = ../jack_control
|
||||
[submodule "siginfo"]
|
||||
path = siginfo
|
||||
url = ../siginfo
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
|
||||
#include <jack/control.h>
|
||||
#define siginfo_log jack_error
|
||||
#include "../siginfo/siginfo.c"
|
220
dbus/sigsegv.c
220
dbus/sigsegv.c
|
@ -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 <jaco@kroon.co.za>
|
||||
*
|
||||
* 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 <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
# include <execinfo.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#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 <ucontext.h>
|
||||
|
||||
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
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef __SIGSEGV_H__
|
||||
#define __SIGSEGV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int setup_sigsegv();
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ba0ec23f8d74c749584910e7c30baebcd368f98a
|
5
wscript
5
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']),
|
||||
|
|
Loading…
Reference in New Issue