diff options
author | Monty <monty@mariadb.org> | 2019-05-17 16:34:35 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2019-05-20 11:22:43 +0300 |
commit | 42504415db5a62677ac9041b83b907e756d8eaf8 (patch) | |
tree | 1d0fdde3f68619d71d684d56cc24917761c93c16 | |
parent | f8ab0ab86783ad5387b02993e1dc6c414c795d84 (diff) | |
download | mariadb-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.txt | 5 | ||||
-rw-r--r-- | client/mysqltest.cc | 2 | ||||
-rw-r--r-- | include/my_stacktrace.h | 4 | ||||
-rw-r--r-- | mysql-test/suite/maria/maria-autozerofill.test | 7 | ||||
-rw-r--r-- | mysys/my_addr_resolve.c | 68 | ||||
-rw-r--r-- | mysys/stacktrace.c | 45 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | storage/maria/maria_chk.c | 7 |
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 */ |