diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e535d2..e4ecd9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ option( ENABLE_EXAMPLES "Install additional tin2rc examples" ON ) option( ENABLE_RSVG "Rsvg support (launcher only)" ON ) option( ENABLE_SN "Startup notification support" ON ) option( ENABLE_ASAN "Build tint2 with AddressSanitizer" OFF ) +option( ENABLE_BACKTRACE "Dump a backtrace in case of fatal errors (e.g. X11 I/O error)" ON ) +option( ENABLE_BACKTRACE_ON_SIGNAL "Dump a backtrace also when receiving signals such as SIGSEGV" ON ) if( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) option( ENABLE_UEVENT "Kernel event handling support" ON ) endif( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) @@ -22,24 +24,33 @@ pkg_check_modules( GLIB2 REQUIRED glib-2.0 ) pkg_check_modules( GOBJECT2 REQUIRED gobject-2.0 ) pkg_check_modules( IMLIB2 REQUIRED imlib2>=1.4.2 ) -check_c_source_compiles( - "#include \n#include \nint main () { backtrace(NULL, 0); }" - BACKTRACE_LIBC) +if(ENABLE_BACKTRACE) + check_c_source_compiles( + "#include \n#include \nint main () { backtrace(NULL, 0); }" + BACKTRACE_LIBC) -if(BACKTRACE_LIBC) - set(BACKTRACE_LIBC_FOUND TRUE) - set(BACKTRACE_L_FLAGS "-rdynamic") -else() - pkg_check_modules( UNWIND libunwind ) - find_library(EXECINFO_LIBRARIES NAMES execinfo) - if(EXECINFO_LIBRARIES OR EXECINFO_LIBRARIES_FOUND) - set(EXECINFO_FOUND TRUE) - set(EXECINFO_LIBRARIES "-lexecinfo") + if(BACKTRACE_LIBC) + set(BACKTRACE_LIBC_FOUND TRUE) set(BACKTRACE_L_FLAGS "-rdynamic") else() - set(EXECINFO_LIBRARIES "") - set(BACKTRACE_L_FLAGS "") + pkg_check_modules( UNWIND libunwind ) + find_library(EXECINFO_LIBRARIES NAMES execinfo) + if(EXECINFO_LIBRARIES OR EXECINFO_LIBRARIES_FOUND) + set(EXECINFO_FOUND TRUE) + set(EXECINFO_LIBRARIES "-lexecinfo") + set(BACKTRACE_L_FLAGS "-rdynamic") + else() + set(EXECINFO_LIBRARIES "") + set(BACKTRACE_L_FLAGS "") + endif() endif() + + if( NOT BACKTRACE_LIBC_FOUND AND NOT UNWIND_FOUND AND NOT EXECINFO_FOUND ) + message( WARNING "Backtrace support not available. You can enable it by installing libexecinfo or libunwind." ) + endif() +else() + set(EXECINFO_LIBRARIES "") + set(BACKTRACE_L_FLAGS "") endif() if( ENABLE_RSVG ) @@ -63,10 +74,6 @@ if( NOT IMLIB_BUILD_WITH_X ) message( FATAL_ERROR "Imlib is not built with X support" ) endif( NOT IMLIB_BUILD_WITH_X ) -if( NOT BACKTRACE_LIBC_FOUND AND NOT UNWIND_FOUND AND NOT EXECINFO_FOUND ) - message( WARNING "Backtrace support not available. You can enable it by installing libexecinfo or libunwind." ) -endif() - add_definitions( -D_GNU_SOURCE ) include_directories( ${PROJECT_BINARY_DIR} @@ -154,18 +161,26 @@ if( ENABLE_UEVENT ) set( SOURCES ${SOURCES} src/util/uevent.c) endif( ENABLE_UEVENT ) -if(BACKTRACE_LIBC_FOUND) - add_definitions( -DENABLE_EXECINFO ) +if(ENABLE_BACKTRACE) + if(BACKTRACE_LIBC_FOUND) + add_definitions( -DENABLE_EXECINFO ) + endif() + + if( UNWIND_FOUND ) + add_definitions( -DENABLE_LIBUNWIND ) + endif( UNWIND_FOUND ) + + if( EXECINFO_FOUND ) + add_definitions( -DENABLE_EXECINFO ) + endif( EXECINFO_FOUND ) + + if(ENABLE_BACKTRACE_ON_SIGNAL) + add_definitions( -DBACKTRACE_ON_SIGNAL ) + endif() +else() + add_definitions( -DDISABLE_BACKTRACE ) endif() -if( UNWIND_FOUND ) - add_definitions( -DENABLE_LIBUNWIND ) -endif( UNWIND_FOUND ) - -if( EXECINFO_FOUND ) - add_definitions( -DENABLE_EXECINFO ) -endif( EXECINFO_FOUND ) - if( ENABLE_TINT2CONF ) add_definitions( -DHAVE_VERSION_H ) add_subdirectory( src/tint2conf ) diff --git a/src/tint.c b/src/tint.c index 617f5da..7160f87 100644 --- a/src/tint.c +++ b/src/tint.c @@ -221,7 +221,9 @@ void dump_backtrace(int log_fd) free(strings); #else - log_string(log_fd, "Backtrace not supported on this system. Install libunwind or libexecinfo.\n"); +#ifdef DISABLE_BACKTRACE + log_string(log_fd, "Backtrace support disabled at compile time.\n"); +#endif #endif #endif log_string(log_fd, RESET); @@ -251,13 +253,17 @@ void handle_crash(const char *reason) dump_backtrace(log_fd); log_string(log_fd, RED "Please create a bug report with this log output.\n" RESET); close(log_fd); - exit(-1); } +#ifdef BACKTRACE_ON_SIGNAL void crash_handler(int sig) { handle_crash(signal_name(sig)); + struct sigaction sa = {.sa_handler = SIG_DFL}; + sigaction(sig, &sa, 0); + raise(sig); } +#endif void x11_io_error(Display *display) { @@ -322,18 +328,20 @@ void init(int argc, char *argv[]) signal_pending = 0; struct sigaction sa = {.sa_handler = signal_handler}; struct sigaction sa_chld = {.sa_handler = SIG_DFL, .sa_flags = SA_NOCLDWAIT}; - struct sigaction sa_crash = {.sa_handler = crash_handler}; sigaction(SIGUSR1, &sa, 0); sigaction(SIGINT, &sa, 0); sigaction(SIGTERM, &sa, 0); sigaction(SIGHUP, &sa, 0); sigaction(SIGCHLD, &sa_chld, 0); +#ifdef BACKTRACE_ON_SIGNAL + struct sigaction sa_crash = {.sa_handler = crash_handler}; sigaction(SIGSEGV, &sa_crash, 0); sigaction(SIGFPE, &sa_crash, 0); sigaction(SIGPIPE, &sa_crash, 0); sigaction(SIGBUS, &sa_crash, 0); sigaction(SIGABRT, &sa_crash, 0); sigaction(SIGSYS, &sa_crash, 0); +#endif } static int sn_pipe_valid = 0;