summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@blame.services>2021-07-06 23:14:09 +0200
committerDave Davenport <qball@blame.services>2021-07-06 23:14:09 +0200
commitafe08def95f697824e994fd5c278d9a669806954 (patch)
tree8f20d0522097df0ddfb71f1d1b5ef76ce5e9903b
parentdc101975aa6824661cb0859e43af5f484caabaa2 (diff)
[unwind] Generate crash report on segfault.unwind
-rwxr-xr-xExamples/test_script_mode.sh2
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--meson.build1
-rw-r--r--source/dialogs/filebrowser.c24
-rw-r--r--source/rofi.c46
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 "<b>Bold</b>"
+ echo -en "<b>Bold</b>\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 ( "<b>Current directory:</b> %s", dirname );
+ char *str = g_markup_printf_escaped ( "<b>Current directory:</b> %s\n\<b>Sort by:</b> %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 <libgwater-xcb.h>
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
#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.