summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2019-05-17 16:34:35 +0300
committerMonty <monty@mariadb.org>2019-05-20 11:22:43 +0300
commit42504415db5a62677ac9041b83b907e756d8eaf8 (patch)
tree1d0fdde3f68619d71d684d56cc24917761c93c16
parentf8ab0ab86783ad5387b02993e1dc6c414c795d84 (diff)
downloadmariadb-git-maria-s3.tar.gz
Make it trivial to get stack traces from external programs.maria-s3
To get a stacktrace in a program like aria_chk, one only have to do: #include <my_stacktrace.h> call my_init_stacktrace(1) in main().
-rw-r--r--CMakeLists.txt5
-rw-r--r--client/mysqltest.cc2
-rw-r--r--include/my_stacktrace.h4
-rw-r--r--mysql-test/suite/maria/maria-autozerofill.test7
-rw-r--r--mysys/my_addr_resolve.c68
-rw-r--r--mysys/stacktrace.c45
-rw-r--r--sql/mysqld.cc2
-rw-r--r--storage/maria/maria_chk.c7
8 files changed, 107 insertions, 33 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 16f908b7e30..fed263db92c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,11 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
+# Remove the following comment if you don't want to have striped binaries
+# in RPM's:
+
+#set(CPACK_RPM_SPEC_MORE_DEFINE "%define __spec_install_post /bin/true")
+
IF(POLICY CMP0022)
CMAKE_POLICY(SET CMP0022 NEW)
ENDIF()
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 80d4d70be2c..7a95c5cd8e8 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -9116,7 +9116,7 @@ static void init_signal_handling(void)
DBUG_ENTER("init_signal_handling");
#ifdef HAVE_STACKTRACE
- my_init_stacktrace();
+ my_init_stacktrace(0);
#endif
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index da22be202ac..c8f05e9db2f 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -41,7 +41,7 @@
C_MODE_START
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
-void my_init_stacktrace();
+void my_init_stacktrace(int setup_handlers);
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack,
my_bool silent);
int my_safe_print_str(const char* val, size_t max_len);
@@ -53,7 +53,7 @@ char *my_demangle(const char *mangled_name, int *status);
void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#endif /* __WIN__ */
#else
-#define my_init_stacktrace() do { } while(0)
+#define my_init_stacktrace(A) do { } while(0)
#endif /* ! (defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)) */
#ifndef _WIN32
diff --git a/mysql-test/suite/maria/maria-autozerofill.test b/mysql-test/suite/maria/maria-autozerofill.test
index 4baa118302c..c24f89576f8 100644
--- a/mysql-test/suite/maria/maria-autozerofill.test
+++ b/mysql-test/suite/maria/maria-autozerofill.test
@@ -115,7 +115,14 @@ check table t5;
# Check that if we zerofill with aria_chk, we should not get any warnings when
# accessing the table
+--error 0,1,11,139
--exec $MARIA_CHK --ignore-control-file --zerofill $MYSQLD_DATADIR/mysqltest/t6 >$MYSQLTEST_VARDIR/tmp/autozerofill.txt 2>&1
+if ($sys_errno != 0)
+{
+--cat_file $MYSQLTEST_VARDIR/tmp/autozerofill.txt
+--die
+}
+
select * from t6;
check table t6;
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index c16f269d574..6a3c5a3801e 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -191,7 +191,9 @@ int start_addr2line_fork(const char *binary_path)
return 0;
}
-int my_addr_resolve(void *ptr, my_addr_loc *loc)
+static int first_error= 0;
+
+static int addr_resolve(void *ptr, my_addr_loc *loc)
{
char input[32];
size_t len;
@@ -206,29 +208,13 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
int filename_start = -1;
int line_number_start = -1;
- Dl_info info;
- void *offset;
-
- if (!dladdr(ptr, &info))
- return 1;
-
- if (strcmp(addr2line_binary, info.dli_fname))
- {
- /* We use dli_fname in case the path is longer than the length of our static
- string. We don't want to allocate anything dynamicaly here as we are in
- a "crashed" state. */
- if (start_addr2line_fork(info.dli_fname))
- {
- addr2line_binary[0] = '\0';
- return 2;
- }
- /* Save result for future comparisons. */
- strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
- }
- offset = info.dli_fbase;
- len= my_snprintf(input, sizeof(input), "%08x\n", (ulonglong)(ptr - offset));
+ len= my_snprintf(input, sizeof(input), "%p\n", ptr);
if (write(in[1], input, len) <= 0)
+ {
+ if (!first_error++)
+ fputs("Printing to addr2line failed\n", stderr);
return 3;
+ }
FD_ZERO(&set);
FD_SET(out[0], &set);
@@ -278,7 +264,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
loc->line= atoi(output + line_number_start);
/* Addr2line was unable to extract any meaningful information. */
- if (strcmp(loc->file, "??") == 0)
+ if (strcmp(loc->file, "??") == 0 && loc->func[0] == '?')
return 6;
loc->file= strip_path(loc->file);
@@ -286,6 +272,42 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
return 0;
}
+
+int my_addr_resolve(void *ptr, my_addr_loc *loc)
+{
+ Dl_info info;
+ int error;
+
+ if (!dladdr(ptr, &info))
+ return 1;
+
+ if (strcmp(addr2line_binary, info.dli_fname))
+ {
+ /*
+ We use dli_fname in case the path is longer than the length of
+ our static string. We don't want to allocate anything
+ dynamicaly here as we are in a "crashed" state.
+ */
+ if (start_addr2line_fork(info.dli_fname))
+ {
+ if (!first_error++)
+ fputs("Can't start addr2line\n", stderr);
+ addr2line_binary[0] = '\0';
+ return 2;
+ }
+ /* Save result for future comparisons. */
+ strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary));
+ }
+ if (!(error= addr_resolve(ptr, loc)))
+ return 0;
+#ifdef EXTRA_RESOLVE
+ if (!(error= addr_resolve((void*) (ptr - info.dli_fbase), loc)))
+ return 0;
+#endif
+ return error;
+}
+
+
const char *my_addr_resolve_init()
{
return 0;
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 619172a5a6a..7064f31777d 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -14,12 +14,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#include <my_global.h>
+#include "mysys_priv.h"
#include <my_stacktrace.h>
#ifndef __WIN__
#include <signal.h>
-#include <my_pthread.h>
#include <m_string.h>
#ifdef HAVE_STACKTRACE
#include <unistd.h>
@@ -42,11 +41,49 @@ static char *heap_start;
extern char *__bss_start;
#endif
-void my_init_stacktrace()
+/**
+ Default handler for printing stacktrace
+*/
+
+static sig_handler default_handle_fatal_signal(int sig)
+{
+ my_safe_printf_stderr("%s: Got signal %d. Attempting backtrace\n",
+ my_progname_short, sig);
+ my_print_stacktrace(0,0,1);
+#ifndef __WIN__
+ signal(sig, SIG_DFL);
+ kill(getpid(), sig);
+#endif /* __WIN__ */
+ return;
+}
+
+
+/**
+ Initialize priting off stacktrace at signal
+
+ @param setup_handlers 0 only initialize variables
+ 1 setup signal handlers for stacktrace printing
+*/
+
+void my_init_stacktrace(int setup_handlers)
{
#if(defined HAVE_BSS_START) && !(defined __linux__)
heap_start = (char*) &__bss_start;
#endif
+ if (setup_handlers)
+ {
+ struct sigaction sa;
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler= default_handle_fatal_signal;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
+#ifdef SIGBUS
+ sigaction(SIGBUS, &sa, NULL);
+#endif
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
+ }
}
#ifdef __linux__
@@ -510,7 +547,7 @@ static EXCEPTION_POINTERS *exception_ptrs;
#define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64
-void my_init_stacktrace()
+void my_init_stacktrace(int setup_handlers __attribute__((unused)))
{
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index dec23535551..f188611a574 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3089,7 +3089,7 @@ void init_signals(void)
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
- my_init_stacktrace();
+ my_init_stacktrace(0);
#if defined(__amiga__)
sa.sa_handler=(void(*)())handle_fatal_signal;
#else
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 598da874256..4beb44948b2 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -26,6 +26,9 @@
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
+/* Remove next line if you want aria_chk to produce a stack trace */
+/* #undef HAVE_BACKTRACE */
+#include <my_stacktrace.h>
static uint decode_bits;
static char **default_argv;
@@ -120,15 +123,15 @@ static void my_exit(int exit_code)
MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(exit_code);
}
-
- /* Main program */
+/* Main program */
int main(int argc, char **argv)
{
int error;
MY_INIT(argv[0]);
+ my_init_stacktrace(1);
default_log_dir= opt_log_dir= maria_data_root= (char *)".";
maria_chk_init(&check_param);
check_param.opt_lock_memory= 1; /* Lock memory if possible */