diff --git a/configure b/configure index 868fd83747a1fb3b9ca23659292ad75d5c0480ac..6bd000f67acdd8a6a63416e34f2fd2432b532d5c 100755 --- a/configure +++ b/configure @@ -13655,6 +13655,7 @@ fi BASEFLAGS=`test "x${LKT_DEBUG_ENABLED}" = 'xyes' && echo "-g" || echo "-O3"` CFLAGS="-Werror -Wall -Wextra ${BASEFLAGS} -std=c11" +LDFLAGS="-rdynamic" ARFLAGS="cr" AR_FLAGS=$ARFLAGS diff --git a/configure.ac b/configure.ac index 4d63bd34e7a3f0e3ab741a417c9d71d8ffef61f4..80569290b63475d2fc61c42db8b2bf6fdde2f2c4 100644 --- a/configure.ac +++ b/configure.ac @@ -145,6 +145,7 @@ fi BASEFLAGS=`test "x${LKT_DEBUG_ENABLED}" = 'xyes' && echo "-g" || echo "-O3"` CFLAGS="-Werror -Wall -Wextra ${BASEFLAGS} -std=c11" +LDFLAGS="-rdynamic" ARFLAGS="cr" AR_FLAGS=$ARFLAGS diff --git a/inc/lektor/segv.h b/inc/lektor/segv.h new file mode 100644 index 0000000000000000000000000000000000000000..8f460cf37747e68afc3f085d5e0c0d20f7c52dcc --- /dev/null +++ b/inc/lektor/segv.h @@ -0,0 +1,6 @@ +#if ! defined(__LKT_SEGV_H__) +#define __LKT_SEGV_H__ + +void install_segv_handler(void); + +#endif /* __LKT_SEGV_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index 58ad65b6b3dde7f38955f4d2d05734807d515947..6296ff3be9d71f7fa0cdd1f3637020c65171873c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,7 @@ endif ## Lib lektor # Base sources liblektor_la_SOURCES = base/bufferfd.c base/cmd.c base/common.c base/config.c base/json.c -liblektor_la_SOURCES += base/reg.c base/uri.c base/commands.c base/stack.c +liblektor_la_SOURCES += base/reg.c base/uri.c base/commands.c base/stack.c base/segv.c # Database sources liblektor_la_SOURCES += database/disk.c database/memory.c @@ -87,7 +87,7 @@ EXTRA_DIST = database/disk.sql database/memory.sql bin_PROGRAMS = lektord lkt ## The lkt client -lkt_SOURCES = main/lkt.c base/cmd.c base/common.c +lkt_SOURCES = main/lkt.c base/cmd.c base/common.c base/segv.c lkt_LDFLAGS = -pthread -ldl -static ## The lektord server diff --git a/src/Makefile.in b/src/Makefile.in index 87ccd656127a86e30744679035b041c265aa3c5b..594be199ca6a23e17f7ce45653d4eaaff35d3345 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -149,12 +149,12 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) @LKT_STATIC_MODULE_TRUE@ liblktmodrepo.la am__liblektor_la_SOURCES_DIST = base/bufferfd.c base/cmd.c \ base/common.c base/config.c base/json.c base/reg.c base/uri.c \ - base/commands.c base/stack.c database/disk.c database/memory.c \ - database/open.c database/playlist.c database/queue.c \ - database/stickers.c database/update.c database/user.c \ - database/config.c database/find.c mkv/mkv.c mkv/utils.c \ - mkv/write.c net/command.c net/listen.c net/message.c \ - module/thread.c + base/commands.c base/stack.c base/segv.c database/disk.c \ + database/memory.c database/open.c database/playlist.c \ + database/queue.c database/stickers.c database/update.c \ + database/user.c database/config.c database/find.c mkv/mkv.c \ + mkv/utils.c mkv/write.c net/command.c net/listen.c \ + net/message.c module/thread.c am__dirstamp = $(am__leading_dot)dirstamp @LKT_STATIC_MODULE_TRUE@am__objects_1 = module/liblektor_la-thread.lo am_liblektor_la_OBJECTS = base/liblektor_la-bufferfd.lo \ @@ -162,8 +162,8 @@ am_liblektor_la_OBJECTS = base/liblektor_la-bufferfd.lo \ base/liblektor_la-config.lo base/liblektor_la-json.lo \ base/liblektor_la-reg.lo base/liblektor_la-uri.lo \ base/liblektor_la-commands.lo base/liblektor_la-stack.lo \ - database/liblektor_la-disk.lo database/liblektor_la-memory.lo \ - database/liblektor_la-open.lo \ + base/liblektor_la-segv.lo database/liblektor_la-disk.lo \ + database/liblektor_la-memory.lo database/liblektor_la-open.lo \ database/liblektor_la-playlist.lo \ database/liblektor_la-queue.lo \ database/liblektor_la-stickers.lo \ @@ -210,7 +210,7 @@ lektord_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lektord_LDFLAGS) $(LDFLAGS) -o $@ am_lkt_OBJECTS = main/lkt.$(OBJEXT) base/cmd.$(OBJEXT) \ - base/common.$(OBJEXT) + base/common.$(OBJEXT) base/segv.$(OBJEXT) lkt_OBJECTS = $(am_lkt_OBJECTS) lkt_LDADD = $(LDADD) lkt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -239,8 +239,9 @@ am__depfiles_remade = base/$(DEPDIR)/cmd.Po base/$(DEPDIR)/common.Po \ base/$(DEPDIR)/liblektor_la-config.Plo \ base/$(DEPDIR)/liblektor_la-json.Plo \ base/$(DEPDIR)/liblektor_la-reg.Plo \ + base/$(DEPDIR)/liblektor_la-segv.Plo \ base/$(DEPDIR)/liblektor_la-stack.Plo \ - base/$(DEPDIR)/liblektor_la-uri.Plo \ + base/$(DEPDIR)/liblektor_la-uri.Plo base/$(DEPDIR)/segv.Po \ database/$(DEPDIR)/liblektor_la-config.Plo \ database/$(DEPDIR)/liblektor_la-disk.Plo \ database/$(DEPDIR)/liblektor_la-find.Plo \ @@ -471,12 +472,12 @@ liblktmodsdl_la_LIBADD = -lSDL2 -lmpv # Net sources liblektor_la_SOURCES = base/bufferfd.c base/cmd.c base/common.c \ base/config.c base/json.c base/reg.c base/uri.c \ - base/commands.c base/stack.c database/disk.c database/memory.c \ - database/open.c database/playlist.c database/queue.c \ - database/stickers.c database/update.c database/user.c \ - database/config.c database/find.c mkv/mkv.c mkv/utils.c \ - mkv/write.c net/command.c net/listen.c net/message.c \ - $(am__append_8) + base/commands.c base/stack.c base/segv.c database/disk.c \ + database/memory.c database/open.c database/playlist.c \ + database/queue.c database/stickers.c database/update.c \ + database/user.c database/config.c database/find.c mkv/mkv.c \ + mkv/utils.c mkv/write.c net/command.c net/listen.c \ + net/message.c $(am__append_8) # Liblektor configuration liblektor_la_CFLAGS = -fPIC @@ -485,7 +486,7 @@ liblektor_la_LDFLAGS = -avoid-version -pthread -lsqlite3 -ldl \ @LKT_STATIC_MODULE_TRUE@liblektor_la_LIBADD = liblktmodsdl.la liblktmodrepo.la CLEANFILES = database/disk.c database/memory.c EXTRA_DIST = database/disk.sql database/memory.sql -lkt_SOURCES = main/lkt.c base/cmd.c base/common.c +lkt_SOURCES = main/lkt.c base/cmd.c base/common.c base/segv.c lkt_LDFLAGS = -pthread -ldl -static lektord_SOURCES = main/server.c lektord_LDADD = liblektor.la @@ -658,6 +659,8 @@ base/liblektor_la-commands.lo: base/$(am__dirstamp) \ base/$(DEPDIR)/$(am__dirstamp) base/liblektor_la-stack.lo: base/$(am__dirstamp) \ base/$(DEPDIR)/$(am__dirstamp) +base/liblektor_la-segv.lo: base/$(am__dirstamp) \ + base/$(DEPDIR)/$(am__dirstamp) database/$(am__dirstamp): @$(MKDIR_P) database @: > database/$(am__dirstamp) @@ -751,6 +754,8 @@ base/cmd.$(OBJEXT): base/$(am__dirstamp) \ base/$(DEPDIR)/$(am__dirstamp) base/common.$(OBJEXT): base/$(am__dirstamp) \ base/$(DEPDIR)/$(am__dirstamp) +base/segv.$(OBJEXT): base/$(am__dirstamp) \ + base/$(DEPDIR)/$(am__dirstamp) lkt$(EXEEXT): $(lkt_OBJECTS) $(lkt_DEPENDENCIES) $(EXTRA_lkt_DEPENDENCIES) @rm -f lkt$(EXEEXT) @@ -782,8 +787,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-config.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-json.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-reg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-segv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-stack.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/liblektor_la-uri.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@base/$(DEPDIR)/segv.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@database/$(DEPDIR)/liblektor_la-config.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@database/$(DEPDIR)/liblektor_la-disk.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@database/$(DEPDIR)/liblektor_la-find.Plo@am__quote@ # am--include-marker @@ -901,6 +908,13 @@ base/liblektor_la-stack.lo: base/stack.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblektor_la_CFLAGS) $(CFLAGS) -c -o base/liblektor_la-stack.lo `test -f 'base/stack.c' || echo '$(srcdir)/'`base/stack.c +base/liblektor_la-segv.lo: base/segv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblektor_la_CFLAGS) $(CFLAGS) -MT base/liblektor_la-segv.lo -MD -MP -MF base/$(DEPDIR)/liblektor_la-segv.Tpo -c -o base/liblektor_la-segv.lo `test -f 'base/segv.c' || echo '$(srcdir)/'`base/segv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) base/$(DEPDIR)/liblektor_la-segv.Tpo base/$(DEPDIR)/liblektor_la-segv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base/segv.c' object='base/liblektor_la-segv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblektor_la_CFLAGS) $(CFLAGS) -c -o base/liblektor_la-segv.lo `test -f 'base/segv.c' || echo '$(srcdir)/'`base/segv.c + database/liblektor_la-disk.lo: database/disk.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblektor_la_CFLAGS) $(CFLAGS) -MT database/liblektor_la-disk.lo -MD -MP -MF database/$(DEPDIR)/liblektor_la-disk.Tpo -c -o database/liblektor_la-disk.lo `test -f 'database/disk.c' || echo '$(srcdir)/'`database/disk.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) database/$(DEPDIR)/liblektor_la-disk.Tpo database/$(DEPDIR)/liblektor_la-disk.Plo @@ -1211,8 +1225,10 @@ distclean: distclean-am -rm -f base/$(DEPDIR)/liblektor_la-config.Plo -rm -f base/$(DEPDIR)/liblektor_la-json.Plo -rm -f base/$(DEPDIR)/liblektor_la-reg.Plo + -rm -f base/$(DEPDIR)/liblektor_la-segv.Plo -rm -f base/$(DEPDIR)/liblektor_la-stack.Plo -rm -f base/$(DEPDIR)/liblektor_la-uri.Plo + -rm -f base/$(DEPDIR)/segv.Po -rm -f database/$(DEPDIR)/liblektor_la-config.Plo -rm -f database/$(DEPDIR)/liblektor_la-disk.Plo -rm -f database/$(DEPDIR)/liblektor_la-find.Plo @@ -1290,8 +1306,10 @@ maintainer-clean: maintainer-clean-am -rm -f base/$(DEPDIR)/liblektor_la-config.Plo -rm -f base/$(DEPDIR)/liblektor_la-json.Plo -rm -f base/$(DEPDIR)/liblektor_la-reg.Plo + -rm -f base/$(DEPDIR)/liblektor_la-segv.Plo -rm -f base/$(DEPDIR)/liblektor_la-stack.Plo -rm -f base/$(DEPDIR)/liblektor_la-uri.Plo + -rm -f base/$(DEPDIR)/segv.Po -rm -f database/$(DEPDIR)/liblektor_la-config.Plo -rm -f database/$(DEPDIR)/liblektor_la-disk.Plo -rm -f database/$(DEPDIR)/liblektor_la-find.Plo diff --git a/src/base/segv.c b/src/base/segv.c new file mode 100644 index 0000000000000000000000000000000000000000..a4d940ab929ca3f19227b1dcadad0f06e6bcc4ef --- /dev/null +++ b/src/base/segv.c @@ -0,0 +1,41 @@ +#define _POSIX_C_SOURCE 200809L + +/* Try to print the backtrace when a segfault occures if possible */ + +#include <lektor/common.h> + +#include <stdio.h> +#include <execinfo.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> + +#define BT_BUF_SIZE 100 + +static void +__segv_handler(int sig) +{ + void *buffer[LKT_BACKLOG]; + int nptrs = backtrace(buffer, LKT_BACKLOG); + LOG_ERROR("SEGV", "Got signal %d", sig); + + char **strings = backtrace_symbols(buffer, nptrs); + if (strings == NULL) { + LOG_ERROR("SEGV", "No backtrace symbol found, abort"); + exit(EXIT_FAILURE); + } + + for (int j = 0; j < nptrs; j++) + LOG_ERROR("SEGV", "[%2d] %s", j, strings[j]); + + free(strings); + exit(EXIT_FAILURE); +} + +void +install_segv_handler(void) +{ + if (SIG_ERR == signal(SIGSEGV, __segv_handler)) + LOG_WARN("SIGNAL", "Failed to install the segv handler"); + LOG_INFO("SIGNAL", "The segv handler has been installed"); +} diff --git a/src/main/lkt.c b/src/main/lkt.c index 7864a168660cefea9a0a25af68d2455366c84e58..e078bdd02ed598410e83f9bc75ff24a8cc717d8f 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -4,6 +4,7 @@ #include <lektor/net.h> #include <lektor/cmd.h> #include <lektor/config.h> +#include <lektor/segv.h> #include <arpa/inet.h> #include <sys/types.h> @@ -1217,6 +1218,7 @@ if (STR_NMATCH(#name, argv[i], len)) { \ int main(int argc, const char **argv) { + install_segv_handler(); __log_level = ERROR; executable_name = "lkt"; assert(NULL != setlocale(LC_ALL, "en_US.UTF-8")); /* BECAUSE! */ diff --git a/src/main/server.c b/src/main/server.c index f6c235e132e75e439b270a72a202460d8d8c8aea..667e0cf09e7ef22ba4b6324b3d0dde40ddee7bca 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -8,6 +8,7 @@ #include <lektor/reg.h> #include <lektor/database.h> #include <lektor/commands.h> +#include <lektor/segv.h> #include <locale.h> #include <signal.h> @@ -83,6 +84,8 @@ __mkdir(const char *dir) int main(int argc, char *argv[]) { + install_segv_handler(); + REG_BEGIN(server_reg) #if defined (LKT_STATIC_MODULE) REG_REGISTER("repo", repo_reg)