commit c9d78d6265acab097f2ec9755493b7720c980634 Author: Jacob Welsh AuthorDate: Mon Aug 3 02:34:37 2020 +0000 Commit: Jacob Welsh CommitDate: Tue Oct 26 02:06:09 2021 +0000 Remove unportable backtrace and core dump features. These broke the build on musl. This also removes a fatal signal handler which only functions to spew blather and interfere with actual debugging. Deleted files: sql/signal_handler.cc Eliminated #defines: BACKTRACE_DEMANGLE DONT_DEFINE_VOID (leftover from an obsolete workaround) HAVE_ABI_CXA_DEMANGLE HAVE_BACKTRACE HAVE_BACKTRACE_SYMBOLS HAVE_BACKTRACE_SYMBOLS_FD HAVE_PRINTSTACK HAVE_STACKTRACE HAVE_WRITE_CORE Eliminated global functions: handle_fatal_signal my_demangle my_init_stacktrace my_print_stacktrace my_safe_print_str my_set_exception_pointers my_unhandler_exception_filter (sic) my_write_core diff --git a/client/mysqltest.cc b/client/mysqltest.cc index dfaa42957cf..7ada18be19b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -45,7 +45,6 @@ #include #endif #include -#include #include // ORACLE_WELCOME_COPYRIGHT_NOTICE @@ -8472,48 +8471,11 @@ void mark_progress(struct st_command* command MY_ATTRIBUTE((unused)), } -#ifdef HAVE_STACKTRACE - -static void dump_backtrace(void) -{ - struct st_connection *conn= cur_con; - - fprintf(stderr, "read_command_buf (%p): ", read_command_buf); - my_safe_print_str(read_command_buf, sizeof(read_command_buf)); - - if (conn) - { - fprintf(stderr, "conn->name (%p): ", conn->name); - my_safe_print_str(conn->name, conn->name_len); -#ifdef EMBEDDED_LIBRARY - fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query); - my_safe_print_str(conn->cur_query, conn->cur_query_len); -#endif - } - fputs("Attempting backtrace...\n", stderr); - my_print_stacktrace(NULL, my_thread_stack_size); -} - -#else - -static void dump_backtrace(void) -{ - fputs("Backtrace not available.\n", stderr); -} - -#endif - static sig_handler signal_handler(int sig) { fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); - dump_backtrace(); - - fprintf(stderr, "Writing a core file...\n"); - fflush(stderr); - my_write_core(sig); -#ifndef __WIN__ - exit(1); // Shouldn't get here but just in case -#endif + fputs("Backtrace not available.\n", stderr); + exit(1); } #ifdef __WIN__ @@ -8560,10 +8522,6 @@ static void init_signal_handling(void) struct sigaction sa; DBUG_ENTER("init_signal_handling"); -#ifdef HAVE_STACKTRACE - my_init_stacktrace(); -#endif - sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 7dfeddf2f31..e499560ef9b 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -28,9 +28,6 @@ SET(HAVE_ALARM CACHE INTERNAL "") SET(HAVE_ALLOCA_H CACHE INTERNAL "") SET(HAVE_ARPA_INET_H CACHE INTERNAL "") SET(HAVE_ASM_MSR_H CACHE INTERNAL "") -SET(HAVE_BACKTRACE CACHE INTERNAL "") -SET(HAVE_BACKTRACE_SYMBOLS CACHE INTERNAL "") -SET(HAVE_BACKTRACE_SYMBOLS_FD CACHE INTERNAL "") SET(HAVE_BMOVE CACHE INTERNAL "") SET(HAVE_BSD_SIGNALS CACHE INTERNAL "") SET(HAVE_BSEARCH 1 CACHE INTERNAL "") @@ -142,7 +139,6 @@ SET(HAVE_PORT_H CACHE INTERNAL "") SET(HAVE_POSIX_FALLOCATE CACHE INTERNAL "") SET(HAVE_POSIX_SIGNALS CACHE INTERNAL "") SET(HAVE_PREAD CACHE INTERNAL "") -SET(HAVE_PRINTSTACK CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_CREATE CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_GETGUARDSIZE CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_GETSTACKSIZE CACHE INTERNAL "") diff --git a/config.h.cmake b/config.h.cmake index fa551f64889..19b26ffd3ca 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -288,11 +288,6 @@ #cmakedefine HAVE_TZNAME 1 #cmakedefine HAVE_AIO_READ 1 /* Symbols we may use */ -/* used by stacktrace functions */ -#cmakedefine HAVE_BACKTRACE 1 -#cmakedefine HAVE_BACKTRACE_SYMBOLS 1 -#cmakedefine HAVE_BACKTRACE_SYMBOLS_FD 1 -#cmakedefine HAVE_PRINTSTACK 1 #cmakedefine HAVE_STRUCT_SOCKADDR_IN6 1 #cmakedefine HAVE_STRUCT_IN6_ADDR 1 #cmakedefine HAVE_NETINET_IN6_H 1 @@ -460,7 +455,6 @@ #cmakedefine HAVE_FLOCKFILE 1 #cmakedefine HAVE_WEAK_SYMBOL 1 -#cmakedefine HAVE_ABI_CXA_DEMANGLE 1 #cmakedefine HAVE_POSIX_SIGNALS 1 diff --git a/configure.cmake b/configure.cmake index ef708925c0c..313a5263fc4 100644 --- a/configure.cmake +++ b/configure.cmake @@ -491,10 +491,6 @@ CHECK_FUNCTION_EXISTS (_aligned_free HAVE_ALIGNED_FREE) CHECK_FUNCTION_EXISTS (aio_read HAVE_AIO_READ) CHECK_FUNCTION_EXISTS (alarm HAVE_ALARM) SET(HAVE_ALLOCA 1) -CHECK_FUNCTION_EXISTS (backtrace HAVE_BACKTRACE) -CHECK_FUNCTION_EXISTS (backtrace_symbols HAVE_BACKTRACE_SYMBOLS) -CHECK_FUNCTION_EXISTS (backtrace_symbols_fd HAVE_BACKTRACE_SYMBOLS_FD) -CHECK_FUNCTION_EXISTS (printstack HAVE_PRINTSTACK) CHECK_FUNCTION_EXISTS (bmove HAVE_BMOVE) CHECK_FUNCTION_EXISTS (bsearch HAVE_BSEARCH) CHECK_FUNCTION_EXISTS (index HAVE_INDEX) @@ -1068,18 +1064,6 @@ ENDIF(NOT HAVE_POSIX_SIGNALS) # Assume regular sprintf SET(SPRINTFS_RETURNS_INT 1) -IF(CMAKE_COMPILER_IS_GNUCXX AND HAVE_CXXABI_H) -CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int argc, char **argv) - { - char *foo= 0; int bar= 0; - foo= abi::__cxa_demangle(foo, foo, 0, &bar); - return 0; - }" - HAVE_ABI_CXA_DEMANGLE) -ENDIF() - CHECK_C_SOURCE_COMPILES(" int main() { diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h index ee038678947..42e3d0bb256 100644 --- a/include/my_stacktrace.h +++ b/include/my_stacktrace.h @@ -18,49 +18,8 @@ #include -#ifdef TARGET_OS_LINUX -#if defined (__x86_64__) || defined (__i386__) || \ - (defined(__alpha__) && defined(__GNUC__)) -#define HAVE_STACKTRACE 1 -#endif -#elif defined(__WIN__) || defined(HAVE_PRINTSTACK) -#define HAVE_STACKTRACE 1 -#endif - -#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) -#undef HAVE_STACKTRACE -#define HAVE_STACKTRACE 1 -#endif - -#define HAVE_WRITE_CORE - -#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && \ - HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE && \ - HAVE_WEAK_SYMBOL -#define BACKTRACE_DEMANGLE 1 -#endif - C_MODE_START -#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE) -void my_init_stacktrace(); -void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack); -void my_safe_print_str(const char* val, int max_len); -void my_write_core(int sig); -#if BACKTRACE_DEMANGLE -char *my_demangle(const char *mangled_name, int *status); -#endif -#ifdef __WIN__ -void my_set_exception_pointers(EXCEPTION_POINTERS *ep); -#endif -#endif - -#ifdef HAVE_WRITE_CORE -void my_write_core(int sig); -#endif - - - /** Async-signal-safe utility functions used by signal handler routines. Declared here in order to unit-test them. diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 16014e5e543..a135b34a215 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -16,706 +16,6 @@ #include #include -#ifndef __WIN__ -#include -#include -#include -#ifdef HAVE_STACKTRACE -#include -#include - -#ifdef __linux__ -#include /* isprint */ -#include /* SYS_gettid */ -#endif - -#if HAVE_EXECINFO_H -#include -#endif - -#ifdef __linux__ -/* __bss_start doesn't seem to work on FreeBSD and doesn't exist on OSX/Solaris. */ -#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) -static char *heap_start; -extern char *__bss_start; -#else -#define PTR_SANE(p) (p) -#endif /* __linux */ - -void my_init_stacktrace() -{ -#ifdef __linux__ - heap_start = (char*) &__bss_start; -#endif /* __linux__ */ -} - -#ifdef __linux__ - -static void print_buffer(char *buffer, size_t count) -{ - const char s[]= " "; - for (; count && *buffer; --count) - { - my_write_stderr(isprint(*buffer) ? buffer : s, 1); - ++buffer; - } -} - -/** - Access the pages of this process through /proc/self/task//mem - in order to safely print the contents of a memory address range. - - @param addr The address at the start of the memory region. - @param max_len The length of the memory region. - - @return Zero on success. -*/ -static int safe_print_str(const char *addr, int max_len) -{ - int fd; - pid_t tid; - off_t offset; - ssize_t nbytes= 0; - size_t total, count; - char buf[256]; - - tid= (pid_t) syscall(SYS_gettid); - - sprintf(buf, "/proc/self/task/%d/mem", tid); - - if ((fd= open(buf, O_RDONLY)) < 0) - return -1; - - /* Ensure that off_t can hold a pointer. */ - compile_time_assert(sizeof(off_t) >= sizeof(intptr)); - - total= max_len; - offset= (intptr) addr; - - /* Read up to the maximum number of bytes. */ - while (total) - { - count= MY_MIN(sizeof(buf), total); - - if ((nbytes= pread(fd, buf, count, offset)) < 0) - { - /* Just in case... */ - if (errno == EINTR) - continue; - else - break; - } - - /* Advance offset into memory. */ - total-= nbytes; - offset+= nbytes; - addr+= nbytes; - - /* Output the printable characters. */ - print_buffer(buf, nbytes); - - /* Break if less than requested... */ - if ((count - nbytes)) - break; - } - - /* Output a new line if something was printed. */ - if (total != (size_t) max_len) - my_safe_printf_stderr("%s", "\n"); - - if (nbytes == -1) - my_safe_printf_stderr("Can't read from address %p\n", addr); - - close(fd); - - return 0; -} - -#endif - -void my_safe_print_str(const char* val, int max_len) -{ -#ifdef __linux__ -/* Only needed by the linux version of PTR_SANE */ - char *heap_end; - - if (!safe_print_str(val, max_len)) - return; - - heap_end= (char*) sbrk(0); -#endif - - if (!PTR_SANE(val)) - { - my_safe_printf_stderr("%s", "is an invalid pointer\n"); - return; - } - - for (; max_len && PTR_SANE(val) && *val; --max_len) - my_write_stderr((val++), 1); - my_safe_printf_stderr("%s", "\n"); -} - -#if defined(HAVE_PRINTSTACK) - -/* Use Solaris' symbolic stack trace routine. */ -#include - -void my_print_stacktrace(uchar* stack_bottom MY_ATTRIBUTE((unused)), - ulong thread_stack MY_ATTRIBUTE((unused))) -{ - if (printstack(fileno(stderr)) == -1) - my_safe_printf_stderr("%s", - "Error when traversing the stack, stack appears corrupt.\n"); - else - my_safe_printf_stderr("%s", - "Please read " - "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" - "and follow instructions on how to resolve the stack trace.\n" - "Resolved stack trace is much more helpful in diagnosing the\n" - "problem, so please do resolve it\n"); -} - -#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) - -#if BACKTRACE_DEMANGLE - -char MY_ATTRIBUTE ((weak)) * -my_demangle(const char *mangled_name MY_ATTRIBUTE((unused)), - int *status MY_ATTRIBUTE((unused))) -{ - return NULL; -} - -static void my_demangle_symbols(char **addrs, int n) -{ - int status, i; - char *begin, *end, *demangled; - - for (i= 0; i < n; i++) - { - demangled= NULL; - begin= strchr(addrs[i], '('); - end= begin ? strchr(begin, '+') : NULL; - - if (begin && end) - { - *begin++= *end++= '\0'; - demangled= my_demangle(begin, &status); - if (!demangled || status) - { - demangled= NULL; - begin[-1]= '('; - end[-1]= '+'; - } - } - - if (demangled) - my_safe_printf_stderr("%s(%s+%s\n", addrs[i], demangled, end); - else - my_safe_printf_stderr("%s\n", addrs[i]); - } -} - -#endif /* BACKTRACE_DEMANGLE */ - -void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) -{ - void *addrs[128]; - char **strings= NULL; - int n = backtrace(addrs, array_elements(addrs)); - my_safe_printf_stderr("stack_bottom = %p thread_stack 0x%lx\n", - stack_bottom, thread_stack); -#if BACKTRACE_DEMANGLE - if ((strings= backtrace_symbols(addrs, n))) - { - my_demangle_symbols(strings, n); - free(strings); - } -#endif -#if HAVE_BACKTRACE_SYMBOLS_FD - if (!strings) - { - backtrace_symbols_fd(addrs, n, fileno(stderr)); - } -#endif -} - -#elif defined(TARGET_OS_LINUX) - -#ifdef __i386__ -#define SIGRETURN_FRAME_OFFSET 17 -#endif - -#ifdef __x86_64__ -#define SIGRETURN_FRAME_OFFSET 23 -#endif - -#if defined(__alpha__) && defined(__GNUC__) -/* - The only way to backtrace without a symbol table on alpha - is to find stq fp,N(sp), and the first byte - of the instruction opcode will give us the value of N. From this - we can find where the old value of fp is stored -*/ - -#define MAX_INSTR_IN_FUNC 10000 - -inline uchar** find_prev_fp(uint32* pc, uchar** fp) -{ - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - uchar* p = (uchar*)pc; - if (p[2] == 222 && p[3] == 35) - { - return (uchar**)((uchar*)fp - *(short int*)p); - } - } - return 0; -} - -inline uint32* find_prev_pc(uint32* pc, uchar** fp) -{ - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - char* p = (char*)pc; - if (p[1] == 0 && p[2] == 94 && p[3] == -73) - { - uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); - return prev_pc; - } - } - return 0; -} -#endif /* defined(__alpha__) && defined(__GNUC__) */ - -void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) -{ - uchar** fp; - uint frame_count = 0, sigreturn_frame_count; -#if defined(__alpha__) && defined(__GNUC__) - uint32* pc; -#endif - LINT_INIT(fp); - - -#ifdef __i386__ - __asm __volatile__ ("movl %%ebp,%0" - :"=r"(fp) - :"r"(fp)); -#endif -#ifdef __x86_64__ - __asm __volatile__ ("movq %%rbp,%0" - :"=r"(fp) - :"r"(fp)); -#endif -#if defined(__alpha__) && defined(__GNUC__) - __asm __volatile__ ("mov $30,%0" - :"=r"(fp) - :"r"(fp)); -#endif - if (!fp) - { - my_safe_printf_stderr("%s", - "frame pointer is NULL, did you compile with\n" - "-fomit-frame-pointer? Aborting backtrace!\n"); - return; - } - - if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp) - { - ulong tmp= MY_MIN(0x10000, thread_stack); - /* Assume that the stack starts at the previous even 65K */ - stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF); - my_safe_printf_stderr("Cannot determine thread, fp=%p, " - "backtrace may not be correct.\n", fp); - } - if (fp > (uchar**) stack_bottom || - fp < (uchar**) stack_bottom - thread_stack) - { - my_safe_printf_stderr("Bogus stack limit or frame pointer, " - "fp=%p, stack_bottom=%p, thread_stack=%ld, " - "aborting backtrace.\n", - fp, stack_bottom, thread_stack); - return; - } - - my_safe_printf_stderr("%s", - "Stack range sanity check OK, backtrace follows:\n"); -#if defined(__alpha__) && defined(__GNUC__) - my_safe_printf_stderr("%s", - "Warning: Alpha stacks are difficult -" - "will be taking some wild guesses, stack trace may be incorrect or " - "terminate abruptly\n"); - - /* On Alpha, we need to get pc */ - __asm __volatile__ ("bsr %0, do_next; do_next: " - :"=r"(pc) - :"r"(pc)); -#endif /* __alpha__ */ - - /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */ - sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1; - - while (fp < (uchar**) stack_bottom) - { -#if defined(__i386__) || defined(__x86_64__) - uchar** new_fp = (uchar**)*fp; - my_safe_printf_stderr("%p\n", - frame_count == sigreturn_frame_count ? - *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1)); -#endif /* defined(__386__) || defined(__x86_64__) */ - -#if defined(__alpha__) && defined(__GNUC__) - uchar** new_fp = find_prev_fp(pc, fp); - if (frame_count == sigreturn_frame_count - 1) - { - new_fp += 90; - } - - if (fp && pc) - { - pc = find_prev_pc(pc, fp); - if (pc) - my_safe_printf_stderr("%p\n", pc); - else - { - my_safe_printf_stderr("%s", - "Not smart enough to deal with the rest of this stack\n"); - goto end; - } - } - else - { - my_safe_printf_stderr("%s", - "Not smart enough to deal with the rest of this stack\n"); - goto end; - } -#endif /* defined(__alpha__) && defined(__GNUC__) */ - if (new_fp <= fp ) - { - my_safe_printf_stderr("New value of fp=%p failed sanity check, " - "terminating stack trace!\n", new_fp); - goto end; - } - fp = new_fp; - ++frame_count; - } - my_safe_printf_stderr("%s", - "Stack trace seems successful - bottom reached\n"); - -end: - my_safe_printf_stderr("%s", - "Please read " - "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" - "and follow instructions on how to resolve the stack trace.\n" - "Resolved stack trace is much more helpful in diagnosing the\n" - "problem, so please do resolve it\n"); -} -#endif /* TARGET_OS_LINUX */ -#endif /* HAVE_STACKTRACE */ - -/* Produce a core for the thread */ -void my_write_core(int sig) -{ - signal(sig, SIG_DFL); - pthread_kill(pthread_self(), sig); -#if defined(P_MYID) && !defined(SCO) - /* On Solaris, the above kill is not enough */ - sigsend(P_PID,P_MYID,sig); -#endif -} - -#else /* __WIN__*/ - -#include -#include -#if _MSC_VER -#pragma comment(lib, "dbghelp") -#endif - -static EXCEPTION_POINTERS *exception_ptrs; - -#define MODULE64_SIZE_WINXP 576 -#define STACKWALK_MAX_FRAMES 64 - -void my_init_stacktrace() -{ -} - - -void my_set_exception_pointers(EXCEPTION_POINTERS *ep) -{ - exception_ptrs = ep; -} - -/* - Appends directory to symbol path. -*/ -static void add_to_symbol_path(char *path, size_t path_buffer_size, - char *dir, size_t dir_buffer_size) -{ - strcat_s(dir, dir_buffer_size, ";"); - if (!strstr(path, dir)) - { - strcat_s(path, path_buffer_size, dir); - } -} - -/* - Get symbol path - semicolon-separated list of directories to search for debug - symbols. We expect PDB in the same directory as corresponding exe or dll, - so the path is build from directories of the loaded modules. If environment - variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path -*/ -static void get_symbol_path(char *path, size_t size) -{ - HANDLE hSnap; - char *envvar; - char *p; -#ifndef DBUG_OFF - static char pdb_debug_dir[MAX_PATH + 7]; -#endif - - path[0]= '\0'; - -#ifndef DBUG_OFF - /* - Add "debug" subdirectory of the application directory, sometimes PDB will - placed here by installation. - */ - GetModuleFileName(NULL, pdb_debug_dir, MAX_PATH); - p= strrchr(pdb_debug_dir, '\\'); - if(p) - { - *p= 0; - strcat_s(pdb_debug_dir, sizeof(pdb_debug_dir), "\\debug;"); - add_to_symbol_path(path, size, pdb_debug_dir, sizeof(pdb_debug_dir)); - } -#endif - - /* - Enumerate all modules, and add their directories to the path. - Avoid duplicate entries. - */ - hSnap= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); - if (hSnap != INVALID_HANDLE_VALUE) - { - BOOL ret; - MODULEENTRY32 mod; - mod.dwSize= sizeof(MODULEENTRY32); - for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod)) - { - char *module_dir= mod.szExePath; - p= strrchr(module_dir,'\\'); - if (!p) - { - /* - Path separator was not found. Not known to happen, if ever happens, - will indicate current directory. - */ - module_dir[0]= '.'; - module_dir[1]= '\0'; - } - else - { - *p= '\0'; - } - add_to_symbol_path(path, size, module_dir,sizeof(mod.szExePath)); - } - CloseHandle(hSnap); - } - - - /* Add _NT_SYMBOL_PATH, if present. */ - envvar= getenv("_NT_SYMBOL_PATH"); - if(envvar) - { - strcat_s(path, size, envvar); - } -} - -#define MAX_SYMBOL_PATH 32768 - -/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/ -#ifndef SYMOPT_NO_PROMPTS -#define SYMOPT_NO_PROMPTS 0 -#endif - -void my_print_stacktrace(uchar* unused1, ulong unused2) -{ - HANDLE hProcess= GetCurrentProcess(); - HANDLE hThread= GetCurrentThread(); - static IMAGEHLP_MODULE64 module= {sizeof(module)}; - static IMAGEHLP_SYMBOL64_PACKAGE package; - DWORD64 addr; - DWORD machine; - int i; - CONTEXT context; - STACKFRAME64 frame={0}; - static char symbol_path[MAX_SYMBOL_PATH]; - - if(!exception_ptrs) - return; - - /* Copy context, as stackwalking on original will unwind the stack */ - context = *(exception_ptrs->ContextRecord); - /*Initialize symbols.*/ - SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG); - get_symbol_path(symbol_path, sizeof(symbol_path)); - SymInitialize(hProcess, symbol_path, TRUE); - - /*Prepare stackframe for the first StackWalk64 call*/ - frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat; -#if (defined _M_IX86) - machine= IMAGE_FILE_MACHINE_I386; - frame.AddrFrame.Offset= context.Ebp; - frame.AddrPC.Offset= context.Eip; - frame.AddrStack.Offset= context.Esp; -#elif (defined _M_X64) - machine = IMAGE_FILE_MACHINE_AMD64; - frame.AddrFrame.Offset= context.Rbp; - frame.AddrPC.Offset= context.Rip; - frame.AddrStack.Offset= context.Rsp; -#else - /*There is currently no need to support IA64*/ -#pragma error ("unsupported architecture") -#endif - - package.sym.SizeOfStruct= sizeof(package.sym); - package.sym.MaxNameLength= sizeof(package.name); - - /*Walk the stack, output useful information*/ - for(i= 0; i< STACKWALK_MAX_FRAMES;i++) - { - DWORD64 function_offset= 0; - DWORD line_offset= 0; - IMAGEHLP_LINE64 line= {sizeof(line)}; - BOOL have_module= FALSE; - BOOL have_symbol= FALSE; - BOOL have_source= FALSE; - - if(!StackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0)) - break; - addr= frame.AddrPC.Offset; - - have_module= SymGetModuleInfo64(hProcess,addr,&module); -#ifdef _M_IX86 - if(!have_module) - { - /* - ModuleInfo structure has been "compatibly" extended in releases after XP, - and its size was increased. To make XP dbghelp.dll function - happy, pretend passing the old structure. - */ - module.SizeOfStruct= MODULE64_SIZE_WINXP; - have_module= SymGetModuleInfo64(hProcess, addr, &module); - } -#endif - - have_symbol= SymGetSymFromAddr64(hProcess, addr, &function_offset, - &(package.sym)); - have_source= SymGetLineFromAddr64(hProcess, addr, &line_offset, &line); - - my_safe_printf_stderr("%p ", addr); - if(have_module) - { - char *base_image_name= strrchr(module.ImageName, '\\'); - if(base_image_name) - base_image_name++; - else - base_image_name= module.ImageName; - my_safe_printf_stderr("%s!", base_image_name); - } - if(have_symbol) - my_safe_printf_stderr("%s()", package.sym.Name); - - else if(have_module) - my_safe_printf_stderr("%s", "???"); - - if(have_source) - { - char *base_file_name= strrchr(line.FileName, '\\'); - if(base_file_name) - base_file_name++; - else - base_file_name= line.FileName; - my_safe_printf_stderr("[%s:%u]", - base_file_name, line.LineNumber); - } - my_safe_printf_stderr("%s", "\n"); - } -} - - -/* - Write dump. The dump is created in current directory, - file name is constructed from executable name plus - ".dmp" extension -*/ -void my_write_core(int unused) -{ - char path[MAX_PATH]; - char dump_fname[MAX_PATH]= "core.dmp"; - MINIDUMP_EXCEPTION_INFORMATION info; - HANDLE hFile; - - if(!exception_ptrs) - return; - - info.ExceptionPointers= exception_ptrs; - info.ClientPointers= FALSE; - info.ThreadId= GetCurrentThreadId(); - - if(GetModuleFileName(NULL, path, sizeof(path))) - { - _splitpath(path, NULL, NULL,dump_fname,NULL); - strncat(dump_fname, ".dmp", sizeof(dump_fname)); - } - - hFile= CreateFile(dump_fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, 0); - if(hFile) - { - /* Create minidump */ - if(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), - hFile, MiniDumpNormal, &info, 0, 0)) - { - my_safe_printf_stderr("Minidump written to %s\n", - _fullpath(path, dump_fname, sizeof(path)) ? - path : dump_fname); - } - else - { - my_safe_printf_stderr("MiniDumpWriteDump() failed, last error %u\n", - (uint) GetLastError()); - } - CloseHandle(hFile); - } - else - { - my_safe_printf_stderr("CreateFile(%s) failed, last error %u\n", - dump_fname, (uint) GetLastError()); - } -} - - -void my_safe_print_str(const char *val, int len) -{ - __try - { - my_write_stderr(val, len); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - my_safe_printf_stderr("%s", "is an invalid string pointer\n"); - } -} -#endif /*__WIN__*/ - - #ifdef __WIN__ size_t my_write_stderr(const void *buf, size_t count) { diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 226f49c6934..2c1b78e091c 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -109,7 +109,6 @@ SET(SQL_SHARED_SOURCES rpl_handler.cc scheduler.cc set_var.cc - signal_handler.cc sp.cc sp_cache.cc sp_head.cc diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 37e3955bbe2..db3017ee545 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -282,8 +282,6 @@ inline void setup_fpu() extern "C" int gethostname(char *name, int namelen); #endif -extern "C" sig_handler handle_fatal_signal(int sig); - #if defined(__linux__) #define ENABLE_TEMP_POOL 1 #else @@ -2863,84 +2861,6 @@ static BOOL WINAPI console_event_handler( DWORD type ) DBUG_RETURN(FALSE); } - - - -#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER -#define DEBUGGER_ATTACH_TIMEOUT 120 -/* - Wait for debugger to attach and break into debugger. If debugger is not attached, - resume after timeout. -*/ -static void wait_for_debugger(int timeout_sec) -{ - if(!IsDebuggerPresent()) - { - int i; - printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId()); - fflush(stdout); - for(i= 0; i < timeout_sec; i++) - { - Sleep(1000); - if(IsDebuggerPresent()) - { - /* Break into debugger */ - __debugbreak(); - return; - } - } - printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(), - timeout_sec); - fflush(stdout); - } -} -#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */ - -LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers) -{ - static BOOL first_time= TRUE; - if(!first_time) - { - /* - This routine can be called twice, typically - when detaching in JIT debugger. - Return EXCEPTION_EXECUTE_HANDLER to terminate process. - */ - return EXCEPTION_EXECUTE_HANDLER; - } - first_time= FALSE; -#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER - /* - Unfortunately there is no clean way to debug unhandled exception filters, - as debugger does not stop there(also documented in MSDN) - To overcome, one could put a MessageBox, but this will not work in service. - Better solution is to print error message and sleep some minutes - until debugger is attached - */ - wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT); -#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */ - __try - { - my_set_exception_pointers(ex_pointers); - handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - DWORD written; - const char msg[] = "Got exception in exception handler!\n"; - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1, - &written,NULL); - } - /* - Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger - (drwtsn32 or vsjitdebugger) possibility to attach, - if JIT debugger is configured. - Windows Error reporting might generate a dump here. - */ - return EXCEPTION_CONTINUE_SEARCH; -} - - void my_init_signals(void) { if(opt_console) @@ -2963,7 +2883,6 @@ void my_init_signals(void) */ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); - SetUnhandledExceptionFilter(my_unhandler_exception_filter); } @@ -2983,15 +2902,6 @@ static void check_data_home(const char *path) #endif /* __WIN__ */ -#if BACKTRACE_DEMANGLE -#include -extern "C" char *my_demangle(const char *mangled_name, int *status) -{ - return abi::__cxa_demangle(mangled_name, NULL, NULL, status); -} -#endif - - #if !defined(__WIN__) #ifndef SA_RESETHAND #define SA_RESETHAND 0 @@ -3010,39 +2920,6 @@ void my_init_signals(void) my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! - if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) - { - sa.sa_flags = SA_RESETHAND | SA_NODEFER; - sigemptyset(&sa.sa_mask); - sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); - -#ifdef HAVE_STACKTRACE - my_init_stacktrace(); -#endif -#if defined(__amiga__) - sa.sa_handler=(void(*)())handle_fatal_signal; -#else - sa.sa_handler=handle_fatal_signal; -#endif - sigaction(SIGSEGV, &sa, NULL); - sigaction(SIGABRT, &sa, NULL); -#ifdef SIGBUS - sigaction(SIGBUS, &sa, NULL); -#endif - sigaction(SIGILL, &sa, NULL); - sigaction(SIGFPE, &sa, NULL); - } - -#ifdef HAVE_GETRLIMIT - if (test_flags & TEST_CORE_ON_SIGNAL) - { - /* Change limits so that we will get a core file */ - STRUCT_RLIMIT rl; - rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; - if (setrlimit(RLIMIT_CORE, &rl) && log_warnings) - sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); - } -#endif (void) sigemptyset(&set); my_sigset(SIGPIPE,SIG_IGN); sigaddset(&set,SIGPIPE); diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc deleted file mode 100644 index e6cd286baa9..00000000000 --- a/sql/signal_handler.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - - 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; version 2 of the License. - - 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "my_global.h" -#include - -#include "sys_vars.h" -#include "my_stacktrace.h" -#include "global_threads.h" - -#ifdef __WIN__ -#include -#define SIGNAL_FMT "exception 0x%x" -#else -#define SIGNAL_FMT "signal %d" -#endif - -/* - We are handling signals in this file. - Any global variables we read should be 'volatile sig_atomic_t' - to guarantee that we read some consistent value. - */ -static volatile sig_atomic_t segfaulted= 0; -extern ulong max_used_connections; -extern volatile sig_atomic_t calling_initgroups; - -/** - * Handler for fatal signals - * - * Fatal events (seg.fault, bus error etc.) will trigger - * this signal handler. The handler will try to dump relevant - * debugging information to stderr and dump a core image. - * - * Signal handlers can only use a set of 'safe' system calls - * and library functions. A list of safe calls in POSIX systems - * are available at: - * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - * For MS Windows, guidelines are available at: - * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx - * - * @param sig Signal number -*/ -extern "C" sig_handler handle_fatal_signal(int sig) -{ - if (segfaulted) - { - my_safe_printf_stderr("Fatal " SIGNAL_FMT " while backtracing\n", sig); - _exit(1); /* Quit without running destructors */ - } - - segfaulted = 1; - -#ifdef __WIN__ - SYSTEMTIME utc_time; - GetSystemTime(&utc_time); - const long hrs= utc_time.wHour; - const long mins= utc_time.wMinute; - const long secs= utc_time.wSecond; -#else - /* Using time() instead of my_time() to avoid looping */ - const time_t curr_time= time(NULL); - /* Calculate time of day */ - const long tmins = curr_time / 60; - const long thrs = tmins / 60; - const long hrs = thrs % 24; - const long mins = tmins % 60; - const long secs = curr_time % 60; -#endif - - char hrs_buf[3]= "00"; - char mins_buf[3]= "00"; - char secs_buf[3]= "00"; - my_safe_itoa(10, hrs, &hrs_buf[2]); - my_safe_itoa(10, mins, &mins_buf[2]); - my_safe_itoa(10, secs, &secs_buf[2]); - - my_safe_printf_stderr("%s:%s:%s UTC - mysqld got " SIGNAL_FMT " ;\n", - hrs_buf, mins_buf, secs_buf, sig); - - my_safe_printf_stderr("%s", - "This could be because you hit a bug. It is also possible that this binary\n" - "or one of the libraries it was linked against is corrupt, improperly built,\n" - "or misconfigured. This error can also be caused by malfunctioning hardware.\n"); - - my_safe_printf_stderr("%s", - "We will try our best to scrape up some info that will hopefully help\n" - "diagnose the problem, but since we have already crashed, \n" - "something is definitely wrong and this may fail.\n\n"); - - my_safe_printf_stderr("key_buffer_size=%lu\n", - (ulong) dflt_key_cache->key_cache_mem_size); - - my_safe_printf_stderr("read_buffer_size=%ld\n", - (long) global_system_variables.read_buff_size); - - my_safe_printf_stderr("max_used_connections=%lu\n", - (ulong) max_used_connections); - - my_safe_printf_stderr("max_threads=%u\n", - (uint) thread_scheduler->max_threads); - - my_safe_printf_stderr("thread_count=%u\n", get_thread_count()); - - my_safe_printf_stderr("connection_count=%u\n", (uint) connection_count); - - my_safe_printf_stderr("It is possible that mysqld could use up to \n" - "key_buffer_size + " - "(read_buffer_size + sort_buffer_size)*max_threads = " - "%lu K bytes of memory\n", - ((ulong) dflt_key_cache->key_cache_mem_size + - (global_system_variables.read_buff_size + - global_system_variables.sortbuff_size) * - thread_scheduler->max_threads + - max_connections * sizeof(THD)) / 1024); - - my_safe_printf_stderr("%s", - "Hope that's ok; if not, decrease some variables in the equation.\n\n"); - -#if defined(HAVE_LINUXTHREADS) -#define UNSAFE_DEFAULT_LINUX_THREADS 200 - if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) - { - my_safe_printf_stderr( - "You seem to be running 32-bit Linux and have " - "%d concurrent connections.\n" - "If you have not changed STACK_SIZE in LinuxThreads " - "and built the binary \n" - "yourself, LinuxThreads is quite likely to steal " - "a part of the global heap for\n" - "the thread stack. Please read " - "http://dev.mysql.com/doc/mysql/en/linux-installation.html\n\n" - thread_count); - } -#endif /* HAVE_LINUXTHREADS */ - -#ifdef HAVE_STACKTRACE - THD *thd=current_thd; - - if (!(test_flags & TEST_NO_STACKTRACE)) - { - my_safe_printf_stderr("Thread pointer: 0x%p\n", thd); - my_safe_printf_stderr("%s", - "Attempting backtrace. You can use the following " - "information to find out\n" - "where mysqld died. If you see no messages after this, something went\n" - "terribly wrong...\n"); - my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, - my_thread_stack_size); - } - if (thd) - { - const char *kreason= "UNKNOWN"; - switch (thd->killed) { - case THD::NOT_KILLED: - kreason= "NOT_KILLED"; - break; - case THD::KILL_BAD_DATA: - kreason= "KILL_BAD_DATA"; - break; - case THD::KILL_CONNECTION: - kreason= "KILL_CONNECTION"; - break; - case THD::KILL_QUERY: - kreason= "KILL_QUERY"; - break; - case THD::KILLED_NO_VALUE: - kreason= "KILLED_NO_VALUE"; - break; - } - my_safe_printf_stderr("%s", "\n" - "Trying to get some variables.\n" - "Some pointers may be invalid and cause the dump to abort.\n"); - - my_safe_printf_stderr("Query (%p): ", thd->query()); - my_safe_print_str(thd->query(), MY_MIN(1024U, thd->query_length())); - my_safe_printf_stderr("Connection ID (thread ID): %lu\n", - (ulong) thd->thread_id); - my_safe_printf_stderr("Status: %s\n\n", kreason); - } - my_safe_printf_stderr("%s", - "The manual page at " - "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n" - "information that should help you find out what is causing the crash.\n"); - -#endif /* HAVE_STACKTRACE */ - -#ifdef HAVE_INITGROUPS - if (calling_initgroups) - { - my_safe_printf_stderr("%s", "\n" - "This crash occured while the server was calling initgroups(). This is\n" - "often due to the use of a mysqld that is statically linked against \n" - "glibc and configured to use LDAP in /etc/nsswitch.conf.\n" - "You will need to either upgrade to a version of glibc that does not\n" - "have this problem (2.3.4 or later when used with nscd),\n" - "disable LDAP in your nsswitch.conf, or use a " - "mysqld that is not statically linked.\n"); - } -#endif - - if (locked_in_memory) - { - my_safe_printf_stderr("%s", "\n" - "The \"--memlock\" argument, which was enabled, " - "uses system calls that are\n" - "unreliable and unstable on some operating systems and " - "operating-system versions (notably, some versions of Linux).\n" - "This crash could be due to use of those buggy OS calls.\n" - "You should consider whether you really need the " - "\"--memlock\" parameter and/or consult the OS distributer about " - "\"mlockall\" bugs.\n"); - } - -#ifdef HAVE_WRITE_CORE - if (test_flags & TEST_CORE_ON_SIGNAL) - { - my_safe_printf_stderr("%s", "Writing a core file\n"); - my_write_core(sig); - } -#endif - -#ifndef __WIN__ - /* - Quit, without running destructors (etc.) - On Windows, do not terminate, but pass control to exception filter. - */ - _exit(1); // Using _exit(), since exit() is not async signal safe -#endif -} diff --git a/storage/ndb/include/ndb_global.h b/storage/ndb/include/ndb_global.h index 02a852380fd..a2022422aa3 100644 --- a/storage/ndb/include/ndb_global.h +++ b/storage/ndb/include/ndb_global.h @@ -18,13 +18,6 @@ #ifndef NDB_GLOBAL_H #define NDB_GLOBAL_H -#ifdef _WIN32 -/* Workaround for Bug#32082: VOID refdefinition results in compile errors */ -#ifndef DONT_DEFINE_VOID -#define DONT_DEFINE_VOID -#endif -#endif - #include #ifdef HAVE_NDB_CONFIG_H diff --git a/storage/ndb/include/util/NdbTap.hpp b/storage/ndb/include/util/NdbTap.hpp index 56e3dfc43d4..cb8a9148ff7 100644 --- a/storage/ndb/include/util/NdbTap.hpp +++ b/storage/ndb/include/util/NdbTap.hpp @@ -36,12 +36,6 @@ int main(int argc, const char** argv){ \ } \ int name##_test() -/* tap.c needs my_print_stacktrace */ -#ifdef DONT_DEFINE_VOID -// stacktrace.c turns off VOID redefinition if needed -#undef DONT_DEFINE_VOID -#endif - #ifdef HAVE_gcov // __gcov_flush need C linkage extern "C" void __gcov_flush(void); @@ -52,7 +46,5 @@ extern "C" void __gcov_flush(void); #define min(a, b) ((a) < (b) ? (a) : (b)) #endif -#include <../../../mysys/stacktrace.c> - #endif diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c index b8e39b5e9f8..69f0e3ff9fb 100644 --- a/unittest/mytap/tap.c +++ b/unittest/mytap/tap.c @@ -20,7 +20,6 @@ #include "tap.h" #include "my_global.h" -#include "my_stacktrace.h" #include #include @@ -124,19 +123,6 @@ emit_endl() fflush(tapout); } -static void -handle_core_signal(int signo) -{ - /* BAIL_OUT("Signal %d thrown", signo); */ -#ifdef HAVE_STACKTRACE - fprintf(stderr, "Signal %d thrown, attempting backtrace.\n", signo); - my_print_stacktrace(NULL, 0); -#endif - signal(signo, SIG_DFL); - raise(signo); - _exit(EXIT_FAILURE); -} - void BAIL_OUT(char const *fmt, ...) { @@ -166,29 +152,6 @@ typedef struct signal_entry { void (*handler)(int); } signal_entry; -static signal_entry install_signal[]= { - { SIGQUIT, handle_core_signal }, - { SIGILL, handle_core_signal }, - { SIGABRT, handle_core_signal }, - { SIGFPE, handle_core_signal }, - { SIGSEGV, handle_core_signal } -#ifdef SIGBUS - , { SIGBUS, handle_core_signal } -#endif -#ifdef SIGXCPU - , { SIGXCPU, handle_core_signal } -#endif -#ifdef SIGXCPU - , { SIGXFSZ, handle_core_signal } -#endif -#ifdef SIGXCPU - , { SIGSYS, handle_core_signal } -#endif -#ifdef SIGXCPU - , { SIGTRAP, handle_core_signal } -#endif -}; - int skip_big_tests= 1; void @@ -200,13 +163,6 @@ plan(int const count) if (config) skip_big_tests= strcmp(config, "big"); - /* - Install signal handler - */ - - for (i= 0; i < sizeof(install_signal)/sizeof(*install_signal); ++i) - signal(install_signal[i].signo, install_signal[i].handler); - g_test.plan= count; switch (count) {