all repos — tint2 @ 76a68fb0715a1bc260e3332023c9d7bc3e069b05

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

Dump stack trace on crash
o9000 mrovi9000@gmail.com
commit

76a68fb0715a1bc260e3332023c9d7bc3e069b05

parent

f511ad2a67a786ba6a707a3fd34c4cdc6d1a0832

2 files changed, 138 insertions(+), 2 deletions(-)

jump to
M CMakeLists.txtCMakeLists.txt

@@ -13,6 +13,7 @@ endif( CMAKE_SYSTEM_NAME STREQUAL "Linux" )

include( FindPkgConfig ) include( CheckLibraryExists ) +include( CheckCSourceCompiles ) pkg_check_modules( X11 REQUIRED x11 xcomposite xdamage xinerama xrender xrandr>=1.3 ) pkg_check_modules( PANGOCAIRO REQUIRED pangocairo ) pkg_check_modules( PANGO REQUIRED pango )

@@ -20,6 +21,19 @@ pkg_check_modules( CAIRO REQUIRED cairo )

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 <stdlib.h>\n#include <execinfo.h>\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 ) + pkg_check_modules( EXECINFO execinfo ) + set(BACKTRACE_L_FLAGS "") +endif() if( ENABLE_RSVG ) pkg_check_modules( RSVG librsvg-2.0>=2.14.0 )

@@ -129,6 +143,18 @@ add_definitions( -DENABLE_UEVENT )

set( SOURCES ${SOURCES} src/util/uevent.c) endif( ENABLE_UEVENT ) +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_TINT2CONF ) add_definitions( -DHAVE_VERSION_H ) add_subdirectory( src/tint2conf )

@@ -166,7 +192,9 @@ ${PANGO_LIBRARIES}

${CAIRO_LIBRARIES} ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES} - ${IMLIB2_LIBRARIES} ) + ${IMLIB2_LIBRARIES} + ${UNWIND_LIBRARIES} + ${EXECINFO_LIBRARIES} ) if( ENABLE_RSVG ) target_link_libraries( tint2 ${RSVG_LIBRARIES} ) endif( ENABLE_RSVG )

@@ -181,7 +209,7 @@ target_link_libraries( tint2 m )

add_dependencies( tint2 version ) set_target_properties( tint2 PROPERTIES COMPILE_FLAGS "-Wall -Wpointer-arith -fno-strict-aliasing -pthread -std=c99 ${ASAN_C_FLAGS}" ) -set_target_properties( tint2 PROPERTIES LINK_FLAGS "-pthread -fno-strict-aliasing ${ASAN_L_FLAGS}" ) +set_target_properties( tint2 PROPERTIES LINK_FLAGS "-pthread -fno-strict-aliasing ${ASAN_L_FLAGS} ${BACKTRACE_L_FLAGS}" ) install( TARGETS tint2 DESTINATION bin ) install( FILES tint2.svg DESTINATION ${DATADIR}/icons/hicolor/scalable/apps )
M src/tint.csrc/tint.c

@@ -51,6 +51,15 @@ #include "timer.h"

#include "xsettings-client.h" #include "uevent.h" +#ifdef ENABLE_LIBUNWIND +#define UNW_LOCAL_ONLY +#include <libunwind.h> +#else +#ifdef ENABLE_EXECINFO +#include <execinfo.h> +#endif +#endif + // Drag and Drop state variables Window dnd_source_window; Window dnd_target_window;

@@ -104,6 +113,98 @@ // signal handler is light as it should be

signal_pending = sig; } +void write_string(int fd, const char *s) +{ + int len = strlen(s); + while (len > 0) { + int count = write(fd, s, len); + if (count >= 0) { + s += count; + len -= count; + } + } +} + +const char *signal_name(int sig) +{ + switch (sig) { + case SIGHUP: return "SIGHUP: Hangup (POSIX)."; + case SIGINT: return "SIGINT: Interrupt (ANSI)."; + case SIGQUIT: return "SIGQUIT: Quit (POSIX)."; + case SIGILL: return "SIGILL: Illegal instruction (ANSI)."; + case SIGTRAP: return "SIGTRAP: Trace trap (POSIX)."; + case SIGABRT: return "SIGABRT/SIGIOT: Abort (ANSI) / IOT trap (4.2 BSD)."; + case SIGBUS: return "SIGBUS: BUS error (4.2 BSD)."; + case SIGFPE: return "SIGFPE: Floating-point exception (ANSI)."; + case SIGKILL: return "SIGKILL: Kill, unblockable (POSIX)."; + case SIGUSR1: return "SIGUSR1: User-defined signal 1 (POSIX)."; + case SIGSEGV: return "SIGSEGV: Segmentation violation (ANSI)."; + case SIGUSR2: return "SIGUSR2: User-defined signal 2 (POSIX)."; + case SIGPIPE: return "SIGPIPE: Broken pipe (POSIX)."; + case SIGALRM: return "SIGALRM: Alarm clock (POSIX)."; + case SIGTERM: return "SIGTERM: Termination (ANSI)."; + case SIGSTKFLT: return "SIGSTKFLT: Stack fault."; + case SIGCHLD: return "SIGCHLD: Child status has changed (POSIX)."; + case SIGCONT: return "SIGCONT: Continue (POSIX)."; + case SIGSTOP: return "SIGSTOP: Stop, unblockable (POSIX)."; + case SIGTSTP: return "SIGTSTP: Keyboard stop (POSIX)."; + case SIGTTIN: return "SIGTTIN: Background read from tty (POSIX)."; + case SIGTTOU: return "SIGTTOU: Background write to tty (POSIX)."; + case SIGURG: return "SIGURG: Urgent condition on socket (4.2 BSD)."; + case SIGXCPU: return "SIGXCPU: CPU limit exceeded (4.2 BSD)."; + case SIGXFSZ: return "SIGXFSZ: File size limit exceeded (4.2 BSD)."; + case SIGVTALRM: return "SIGVTALRM: Virtual alarm clock (4.2 BSD)."; + case SIGPROF: return "SIGPROF: Profiling alarm clock (4.2 BSD)."; + case SIGWINCH: return "SIGWINCH: Window size change (4.3 BSD, Sun)."; + case SIGIO: return "SIGIO: Pollable event occurred (System V) / I/O now possible (4.2 BSD)."; + case SIGPWR: return "SIGPWR: Power failure restart (System V)."; + case SIGSYS: return "SIGSYS: Bad system call."; + } + static char s[64]; + sprintf(s, "SIG=%d: Unknown", sig); + return s; +} + +void crash_handler(int sig) +{ + write_string(2, "Crashing with signal "); + write_string(2, signal_name(sig)); + write_string(2, "\nBacktrace:\n"); + +#ifdef ENABLE_LIBUNWIND + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + while (unw_step(&cursor) > 0) { + unw_word_t offset; + char fname[128]; + fname[0] = '\0'; + (void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset); + write_string(2, fname); + write_string(2, "\n"); + } +#else +#ifdef ENABLE_EXECINFO +#define MAX_TRACE_SIZE 128 + void *array[MAX_TRACE_SIZE]; + size_t size = backtrace(array, MAX_TRACE_SIZE); + char **strings = backtrace_symbols(array, size); + + for (size_t i = 0; i < size; i++) { + write_string(2, strings[i]); + write_string(2, "\n"); + } + + free(strings); +#else + write_string(2, "Backtrace not supported on this system. Install libunwind or libexecinfo.\n"); +#endif +#endif + _exit(sig); +} + void init(int argc, char *argv[]) { // Make stdout/stderr flush after a newline (for some reason they don't even if tint2 is started from a terminal)

@@ -162,11 +263,18 @@ // Set signal handlers

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); + 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); } static int sn_pipe_valid = 0;