diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c74fe0f..d0e84ef0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ set(AWE_SRCS ${SOURCE_DIR}/common/xembed.c ${SOURCE_DIR}/common/xutil.c ${SOURCE_DIR}/common/xcursor.c + ${SOURCE_DIR}/common/backtrace.c ${SOURCE_DIR}/widgets/graph.c ${SOURCE_DIR}/widgets/progressbar.c ${SOURCE_DIR}/widgets/textbox.c diff --git a/awesome.c b/awesome.c index 4e0775f8..fd8ecd70 100644 --- a/awesome.c +++ b/awesome.c @@ -46,6 +46,7 @@ #include "common/atoms.h" #include "common/xcursor.h" #include "common/xutil.h" +#include "common/backtrace.h" awesome_t globalconf; @@ -234,6 +235,14 @@ xerrorstart(void * data __attribute__ ((unused)), fatal("another window manager is already running"); } +static void +signal_fatal(EV_P_ ev_signal *w, int revents) +{ + buffer_t buf; + backtrace_get(&buf); + fatal("dumping backtrace\n%s", buf.s); +} + /** Function to exit on some signals. * \param sig the signal received, unused */ @@ -399,6 +408,7 @@ main(int argc, char **argv) ev_signal_init(&sigint, exit_on_signal, SIGINT); ev_signal_init(&sigterm, exit_on_signal, SIGTERM); ev_signal_init(&sighup, restart_on_signal, SIGHUP); + ev_signal_init(&sighup, signal_fatal, SIGSEGV); ev_signal_start(globalconf.loop, &sigint); ev_signal_start(globalconf.loop, &sigterm); ev_signal_start(globalconf.loop, &sighup); diff --git a/common/backtrace.c b/common/backtrace.c new file mode 100644 index 00000000..96a8f0e0 --- /dev/null +++ b/common/backtrace.c @@ -0,0 +1,55 @@ +/* + * common/backtrace.c - Backtrace handling functions + * + * Copyright © 2009 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include "common/backtrace.h" + +#define MAX_STACK_SIZE 32 + +/** Get a backtrace. + * \param buf The buffer to fill with backtrace. + */ +void +backtrace_get(buffer_t *buf) +{ + void *stack[MAX_STACK_SIZE]; + char **bt; + int stack_size; + + stack_size = backtrace(stack, countof(stack)); + bt = backtrace_symbols(stack, stack_size); + + buffer_init(buf); + if(bt) + { + for(int i = 0; i < stack_size; i++) + { + if(i > 0) + buffer_addsl(buf, "\n"); + buffer_adds(buf, bt[i]); + } + p_delete(&bt); + } + else + buffer_addsl(buf, "Cannot get backtrace symbols."); +} + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/common/backtrace.h b/common/backtrace.h new file mode 100644 index 00000000..25a3e1e9 --- /dev/null +++ b/common/backtrace.h @@ -0,0 +1,31 @@ +/* + * common/backtrace.h - Backtrace handling + * + * Copyright © 2009 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef AWESOME_COMMON_BACKTRACE +#define AWESOME_COMMON_BACKTRACE + +#include "common/buffer.h" + +void backtrace_get(buffer_t *); + +#endif + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80