Enable backtraces on C tests
diff --git a/Makefile b/Makefile
index 7091849..e0a7b80 100644
--- a/Makefile
+++ b/Makefile
@@ -92,7 +92,7 @@
LD_opt = $(DEFAULT_CC)
LDXX_opt = $(DEFAULT_CXX)
CPPFLAGS_opt = -O2
-LDFLAGS_opt =
+LDFLAGS_opt = -rdynamic
DEFINES_opt = NDEBUG
VALID_CONFIG_basicprof = 1
@@ -119,7 +119,7 @@
LD_dbg = $(DEFAULT_CC)
LDXX_dbg = $(DEFAULT_CXX)
CPPFLAGS_dbg = -O0
-LDFLAGS_dbg =
+LDFLAGS_dbg = -rdynamic
DEFINES_dbg = _DEBUG DEBUG
VALID_CONFIG_mutrace = 1
@@ -139,7 +139,7 @@
LDXX_valgrind = $(DEFAULT_CXX)
CPPFLAGS_valgrind = -O0
OPENSSL_CFLAGS_valgrind = -DPURIFY
-LDFLAGS_valgrind =
+LDFLAGS_valgrind = -rdynamic
DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
VALID_CONFIG_tsan = 1
@@ -190,7 +190,7 @@
LD_gcov = gcc
LDXX_gcov = g++
CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage
-LDFLAGS_gcov = -fprofile-arcs -ftest-coverage
+LDFLAGS_gcov = -fprofile-arcs -ftest-coverage -rdynamic
DEFINES_gcov = _DEBUG DEBUG
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 93291a1..0798b6e 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -121,6 +121,7 @@
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#elif defined(__linux__)
+#define GPR_POSIX_CRASH_HANDLER 1
#define GPR_PLATFORM_STRING "linux"
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
@@ -188,6 +189,7 @@
#define GPR_PLATFORM_STRING "osx"
#define GPR_CPU_POSIX 1
#define GPR_GCC_TLS 1
+#define GPR_POSIX_CRASH_HANDLER 1
#endif
#define GPR_GCC_ATOMIC 1
#define GPR_POSIX_LOG 1
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 8f79fdb..115d813 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -108,7 +108,7 @@
LD_opt = $(DEFAULT_CC)
LDXX_opt = $(DEFAULT_CXX)
CPPFLAGS_opt = -O2
- LDFLAGS_opt =
+ LDFLAGS_opt = -rdynamic
DEFINES_opt = NDEBUG
VALID_CONFIG_basicprof = 1
@@ -135,7 +135,7 @@
LD_dbg = $(DEFAULT_CC)
LDXX_dbg = $(DEFAULT_CXX)
CPPFLAGS_dbg = -O0
- LDFLAGS_dbg =
+ LDFLAGS_dbg = -rdynamic
DEFINES_dbg = _DEBUG DEBUG
VALID_CONFIG_mutrace = 1
@@ -155,7 +155,7 @@
LDXX_valgrind = $(DEFAULT_CXX)
CPPFLAGS_valgrind = -O0
OPENSSL_CFLAGS_valgrind = -DPURIFY
- LDFLAGS_valgrind =
+ LDFLAGS_valgrind = -rdynamic
DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
VALID_CONFIG_tsan = 1
@@ -206,7 +206,7 @@
LD_gcov = gcc
LDXX_gcov = g++
CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage
- LDFLAGS_gcov = -fprofile-arcs -ftest-coverage
+ LDFLAGS_gcov = -fprofile-arcs -ftest-coverage -rdynamic
DEFINES_gcov = _DEBUG DEBUG
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 168b98f..c3d356c 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -83,6 +83,50 @@
_set_abort_behavior(0, _CALL_REPORTFAULT);
signal(SIGABRT, abort_handler);
}
+#elif GPR_POSIX_CRASH_HANDLER
+#include <execinfo.h>
+#include <stdio.h>
+#include <string.h>
+#include <grpc/support/useful.h>
+
+static char g_alt_stack[8192];
+
+#define MAX_FRAMES 32
+
+static void crash_handler(int signum, siginfo_t *info, void *data) {
+ void *addrlist[MAX_FRAMES + 1];
+ int addrlen;
+ int i;
+ char **symlist;
+
+ fprintf(stderr, "Caught signal %d\n", signum);
+ addrlen = backtrace(addrlist, GPR_ARRAY_SIZE(addrlist));
+
+ symlist = backtrace_symbols(addrlist, addrlen);
+ for (i = 0; i < addrlen; i++) {
+ fprintf(stderr, " %s\n", symlist[i]);
+ }
+ free(symlist);
+
+ raise(signum);
+}
+
+static void install_crash_handler() {
+ stack_t ss;
+ struct sigaction sa;
+ memset(&ss, 0, sizeof(ss));
+ memset(&sa, 0, sizeof(sa));
+ ss.ss_size = sizeof(g_alt_stack);
+ ss.ss_sp = g_alt_stack;
+ GPR_ASSERT(sigaltstack(&ss, NULL) == 0);
+ sa.sa_flags = (int)(SA_SIGINFO | SA_ONSTACK | SA_RESETHAND);
+ sa.sa_sigaction = crash_handler;
+ GPR_ASSERT(sigaction(SIGILL, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGABRT, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGSEGV, &sa, NULL) == 0);
+ GPR_ASSERT(sigaction(SIGSTKFLT, &sa, NULL) == 0);
+}
#else
static void install_crash_handler() {}
#endif