From afe08def95f697824e994fd5c278d9a669806954 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Tue, 6 Jul 2021 23:14:09 +0200 Subject: [unwind] Generate crash report on segfault. --- Examples/test_script_mode.sh | 2 +- Makefile.am | 2 ++ configure.ac | 1 + meson.build | 1 + source/dialogs/filebrowser.c | 24 ++++++++++++++++++++++- source/rofi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 2 deletions(-) diff --git a/Examples/test_script_mode.sh b/Examples/test_script_mode.sh index d2773ae3..0c592457 100755 --- a/Examples/test_script_mode.sh +++ b/Examples/test_script_mode.sh @@ -26,6 +26,6 @@ else echo "mies" echo -en "-------------\0nonselectable\x1ftrue\n" echo "testing" - echo "Bold" + echo -en "Bold\x00meta\x1fclapton.\n" echo "quit" fi diff --git a/Makefile.am b/Makefile.am index b4528d7a..b487c70c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -145,6 +145,7 @@ rofi_CFLAGS=\ $(pango_CFLAGS)\ $(libsn_CFLAGS)\ $(cairo_CFLAGS)\ + $(unwind_CFLAGS)\ $(gdkpixbuf_CFLAGS)\ -DMANPAGE_PATH="\"$(mandir)/\""\ -I$(top_srcdir)/include/\ @@ -165,6 +166,7 @@ rofi_LDADD=\ $(libsn_LIBS)\ $(pango_LIBS)\ $(cairo_LIBS)\ + $(unwind_LIBS)\ $(gdkpixbuf_LIBS)\ $(LIBS) diff --git a/configure.ac b/configure.ac index 3472dffd..13adec38 100644 --- a/configure.ac +++ b/configure.ac @@ -149,6 +149,7 @@ PKG_CHECK_MODULES([pango], [pango pangocairo]) PKG_CHECK_MODULES([cairo], [cairo cairo-xcb]) PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0 ]) PKG_CHECK_MODULES([gdkpixbuf], [gdk-pixbuf-2.0]) +PKG_CHECK_MODULES([unwind], [libunwind]) dnl --------------------------------------------------------------------- dnl check - Unit testing. diff --git a/meson.build b/meson.build index 82c1117e..769c2b9e 100644 --- a/meson.build +++ b/meson.build @@ -69,6 +69,7 @@ deps += [ dependency('xcb-xinerama'), dependency('cairo-xcb'), dependency('libstartup-notification-1.0'), + dependency('libunwind'), ] check = dependency('check', version: '>= 0.11.0', required: get_option('check')) diff --git a/source/dialogs/filebrowser.c b/source/dialogs/filebrowser.c index 750ea97b..fc261211 100644 --- a/source/dialogs/filebrowser.c +++ b/source/dialogs/filebrowser.c @@ -541,12 +541,34 @@ static cairo_surface_t *_get_icon ( const Mode *sw, unsigned int selected_line, return rofi_icon_fetcher_get ( dr->icon_fetch_uid ); } +static const char * _get_sort_method ( void ) +{ + switch ( file_browser_config.sorting_method ) + { + default: + case FB_SORT_NAME: + return "name"; + case FB_SORT_TIME: + switch ( file_browser_config.sorting_time ) + { + case FB_MTIME: + return "modification time"; + case FB_ATIME: + return "access time"; + case FB_CTIME: + default: + return "creation time"; + } + } +} + static char * _get_message ( const Mode *sw ) { FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *) mode_get_private_data ( sw ); if ( pd->current_dir ) { char *dirname = g_file_get_parse_name ( pd->current_dir ); - char *str = g_markup_printf_escaped ( "Current directory: %s", dirname ); + char *str = g_markup_printf_escaped ( "Current directory: %s\n\Sort by: %s", dirname, + _get_sort_method()); g_free ( dirname ); return str; } diff --git a/source/rofi.c b/source/rofi.c index a94d4611..8cc99c15 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -47,6 +47,9 @@ #include +#define UNW_LOCAL_ONLY +#include + #ifdef USE_NK_GIT_VERSION #include "nkutils-git-version.h" #ifdef NK_GIT_VERSION @@ -679,6 +682,47 @@ static gboolean main_loop_signal_handler_int ( G_GNUC_UNUSED gpointer data ) g_main_loop_quit ( main_loop ); return G_SOURCE_CONTINUE; } + +static void send_backtrace_to_monitor(void) { + unw_cursor_t cursor; + unw_context_t context; + + fprintf(stderr, "----------===== Backtrace =====----------\n"); + // grab the machine context and initialize the cursor + if (unw_getcontext(&context) < 0) { + fprintf(stderr, "ERROR: cannot get local machine state\n"); + } + if (unw_init_local(&cursor, &context) < 0) { + fprintf(stderr,"ERROR: cannot initialize cursor for local unwinding\n"); + } + + + // currently the IP is within backtrace() itself so this loop + // deliberately skips the first frame. + while (unw_step(&cursor) > 0) { + unw_word_t offset = 0, pc = 0; + char sym[4096]; + if (unw_get_reg(&cursor, UNW_REG_IP, &pc)) { + fprintf(stderr,"ERROR: cannot read program counter\n"); + } + + fprintf(stderr, "0x%lx: ", pc); + + if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) { + fprintf(stderr,"(%s +0x%lx)\n", sym, offset); + } else { + fprintf(stderr, "-- no symbol name found\n"); + } + } + fprintf(stderr, "----------===== Backtrace =====----------\n"); +} + +static void main_loop_signal_handler_sigsegv_int ( int signr ) +{ + signal(signr, SIG_DFL); /* Set it back immediately. */ + send_backtrace_to_monitor(); + raise(signr); +} static void show_error_dialog () { GString *emesg = g_string_new ( "The following errors were detected when starting rofi:\n" ); @@ -1073,6 +1117,8 @@ int main ( int argc, char *argv[] ) // SIGINT g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL ); + signal ( SIGSEGV, main_loop_signal_handler_sigsegv_int ); + g_idle_add ( startup, NULL ); // Start mainloop. -- cgit v1.2.3