Commit fb8f32d0 authored by Davi Arnaut's avatar Davi Arnaut

Bug#37003 Tests sporadically crashes with embedded server

The problem was that when a embedded linked version of mysqltest
crashed there was no way to obtain a stack trace if no core file
is available. Another problem is that the embedded version of
libmysql was not behaving (crash) the same as the non-embedded with
respect to sending commands to a explicitly closed connection.

The solution is to generate a mysqltest's stack trace on crash
and to enable "reconnect" if the connection handle was explicitly
closed so the behavior matches the non-embedded one.

client/CMakeLists.txt:
  Link mysys to mysqltest.
client/Makefile.am:
  Link mysys to mysqltest.
client/mysqltest.c:
  Add fatal signal handling with backtracing for Unix and Windows.
configure.in:
  Add check for weak symbols support and remove a spurious word.
include/Makefile.am:
  Add new header with prototype for stack tracing functions.
include/my_stacktrace.h:
  Add new header with prototype for stack tracing functions.
libmysqld/CMakeLists.txt:
  stack tracing is now part of mysys.
libmysqld/Makefile.am:
  stack tracing is now part of mysys.
libmysqld/lib_sql.cc:
  Re-connect if connection was explicitly closed. This is
  done to match the behavior of the non-embeded libmysql.
mysql-test/t/sql_low_priority_updates_func.test:
  Test expects parallelism between queries that cannot be
  guaranteed under embedded.
mysys/CMakeLists.txt:
  Add stacktrace to mysys.
mysys/Makefile.am:
  Add stacktrace to mysys.
mysys/stacktrace.c:
  Move stacktrace to mysys and add weak symbol for the
  C++ name de-mangling function so that it can later be
  overridden in C++ code. Also add my_ prefix to exported
  functions.
sql/CMakeLists.txt:
  stacktrace was moved to mysys.
sql/Makefile.am:
  stacktrace was moved to mysys.
sql/mysqld.cc:
  Add my_ prefix to mysys functions.
parent 5d237db6
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
# We use the "mysqlclient_notls" library here just as safety, in case # We use the "mysqlclient_notls" library here just as safety, in case
# any of the clients here would go beond the client API and access the # any of the clients here would go beyond the client API and access the
# Thread Local Storage directly. # Thread Local Storage directly.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
...@@ -32,9 +32,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ...@@ -32,9 +32,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ADD_EXECUTABLE(mysqltest mysqltest.c)
../mysys/my_copy.c ../mysys/my_mkdir.c) SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
......
...@@ -86,11 +86,13 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ ...@@ -86,11 +86,13 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
$(LIBMYSQLCLIENT_LA) \ $(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a $(top_builddir)/mysys/libmysys.a
mysqltest_SOURCES= mysqltest.c \ mysqltest_SOURCES= mysqltest.c
$(top_srcdir)/mysys/my_getsystime.c \ mysqltest_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
$(top_srcdir)/mysys/my_copy.c \ mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
$(top_srcdir)/mysys/my_mkdir.c @CLIENT_EXTRA_LDFLAGS@ \
mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) $(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/regex/libregex.a
mysql_upgrade_SOURCES= mysql_upgrade.c \ mysql_upgrade_SOURCES= mysql_upgrade.c \
$(top_srcdir)/mysys/my_getpagesize.c $(top_srcdir)/mysys/my_getpagesize.c
......
...@@ -48,7 +48,14 @@ ...@@ -48,7 +48,14 @@
#ifdef __WIN__ #ifdef __WIN__
#include <direct.h> #include <direct.h>
#endif #endif
#include <my_stacktrace.h>
#ifdef __WIN__
#include <crtdbg.h>
#define SIGNAL_FMT "exception 0x%x"
#else
#define SIGNAL_FMT "signal %d"
#endif
/* Use cygwin for --exec and --system before 5.0 */ /* Use cygwin for --exec and --system before 5.0 */
#if MYSQL_VERSION_ID < 50000 #if MYSQL_VERSION_ID < 50000
...@@ -214,6 +221,7 @@ struct st_connection ...@@ -214,6 +221,7 @@ struct st_connection
/* Used when creating views and sp, to avoid implicit commit */ /* Used when creating views and sp, to avoid implicit commit */
MYSQL* util_mysql; MYSQL* util_mysql;
char *name; char *name;
size_t name_len;
MYSQL_STMT* stmt; MYSQL_STMT* stmt;
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
...@@ -4436,6 +4444,7 @@ void do_connect(struct st_command *command) ...@@ -4436,6 +4444,7 @@ void do_connect(struct st_command *command)
ds_connection_name.str)); ds_connection_name.str));
if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
die("Out of memory"); die("Out of memory");
con_slot->name_len= strlen(con_slot->name);
cur_con= con_slot; cur_con= con_slot;
if (con_slot == next_con) if (con_slot == next_con)
...@@ -6839,6 +6848,87 @@ void mark_progress(struct st_command* command __attribute__((unused)), ...@@ -6839,6 +6848,87 @@ void mark_progress(struct st_command* command __attribute__((unused)),
} }
static sig_handler dump_backtrace(int sig)
{
struct st_connection *conn= cur_con;
fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
my_safe_print_str("read_command_buf", read_command_buf,
sizeof(read_command_buf));
if (conn)
{
my_safe_print_str("conn->name", conn->name, conn->name_len);
#ifdef EMBEDDED_LIBRARY
my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len);
#endif
}
fputs("Attempting backtrace...\n", stderr);
my_print_stacktrace(NULL, my_thread_stack_size);
}
#ifdef __WIN__
LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
{
__try
{
my_set_exception_pointers(exp);
dump_backtrace(exp->ExceptionRecord->ExceptionCode);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
fputs("Got exception in exception handler!\n", stderr);
}
return EXCEPTION_CONTINUE_SEARCH;
}
static void init_signal_handling(void)
{
UINT mode;
/* Set output destination of messages to the standard error stream. */
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
/* Do not not display the a error message box. */
mode= SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
SetErrorMode(mode);
SetUnhandledExceptionFilter(exception_filter);
}
#else /* __WIN__ */
static void init_signal_handling(void)
{
struct sigaction sa;
DBUG_ENTER("init_signal_handling");
my_init_stacktrace();
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
sa.sa_handler= dump_backtrace;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
#ifdef SIGBUS
sigaction(SIGBUS, &sa, NULL);
#endif
sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
}
#endif /* !__WIN__ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct st_command *command; struct st_command *command;
...@@ -6851,6 +6941,8 @@ int main(int argc, char **argv) ...@@ -6851,6 +6941,8 @@ int main(int argc, char **argv)
save_file[0]= 0; save_file[0]= 0;
TMPDIR[0]= 0; TMPDIR[0]= 0;
init_signal_handling();
/* Init expected errors */ /* Init expected errors */
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
......
...@@ -2341,10 +2341,20 @@ then ...@@ -2341,10 +2341,20 @@ then
fi fi
AC_MSG_RESULT("$netinet_inc") AC_MSG_RESULT("$netinet_inc")
AC_CACHE_CHECK([support for weak symbols], mysql_cv_weak_symbol,
[AC_TRY_LINK([],[
extern void __attribute__((weak)) foo(void);
], [mysql_cv_weak_symbol=yes], [mysql_cv_weak_symbol=no])])
if test "x$mysql_cv_weak_symbol" = xyes; then
AC_DEFINE(HAVE_WEAK_SYMBOL, 1,
[Define to 1 if compiler supports weak symbol attribute.])
fi
AC_LANG_SAVE AC_LANG_SAVE
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(cxxabi.h) AC_CHECK_HEADERS(cxxabi.h)
AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle, AC_CACHE_CHECK([for abi::__cxa_demangle], mysql_cv_cxa_demangle,
[AC_TRY_LINK([#include <cxxabi.h>], [ [AC_TRY_LINK([#include <cxxabi.h>], [
char *foo= 0; int bar= 0; char *foo= 0; int bar= 0;
foo= abi::__cxa_demangle(foo, foo, 0, &bar); foo= abi::__cxa_demangle(foo, foo, 0, &bar);
......
...@@ -36,7 +36,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ ...@@ -36,7 +36,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \
mysql_version.h.in my_handler.h my_time.h \ mysql_version.h.in my_handler.h my_time.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
atomic/gcc_builtins.h my_libwrap.h atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h
# Remove built files and the symlinked directories # Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl CLEANFILES = $(BUILT_SOURCES) readline openssl
......
...@@ -13,57 +13,49 @@ ...@@ -13,57 +13,49 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __cplusplus #ifndef _my_stacktrace_h_
extern "C" { #define _my_stacktrace_h_
#include <my_global.h>
#ifdef TARGET_OS_LINUX
#if defined (__x86_64__) || defined (__i386__) || \
(defined(__alpha__) && defined(__GNUC__))
#define HAVE_STACKTRACE 1
#endif
#elif defined(__WIN__)
#define HAVE_STACKTRACE 1
#endif
#if !defined(__NETWARE__)
#define HAVE_WRITE_CORE
#endif #endif
#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE #if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && \
HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE && \
HAVE_WEAK_SYMBOL
#define BACKTRACE_DEMANGLE 1 #define BACKTRACE_DEMANGLE 1
#endif #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* name, const char* val, int max_len);
void my_write_core(int sig);
#if BACKTRACE_DEMANGLE #if BACKTRACE_DEMANGLE
char *my_demangle(const char *mangled_name, int *status); char *my_demangle(const char *mangled_name, int *status);
#endif #endif
#ifdef __WIN__
#ifdef TARGET_OS_LINUX void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE
extern char* __bss_start;
extern char* heap_start;
#define init_stacktrace() do { \
heap_start = (char*) &__bss_start; \
} while(0);
void check_thread_lib(void);
#endif /* defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#elif defined (__WIN__)
#define HAVE_STACKTRACE
extern void set_exception_pointers(EXCEPTION_POINTERS *ep);
#define init_stacktrace() {}
#endif #endif
#ifdef HAVE_STACKTRACE
void print_stacktrace(uchar* stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len);
#else
/* Define empty prototypes for functions that are not implemented */
#define init_stacktrace() {}
#define print_stacktrace(A,B) {}
#define safe_print_str(A,B,C) {}
#endif /* HAVE_STACKTRACE */
#if !defined(__NETWARE__)
#define HAVE_WRITE_CORE
#endif #endif
#ifdef HAVE_WRITE_CORE #ifdef HAVE_WRITE_CORE
void write_core(int sig); void my_write_core(int sig);
#endif #endif
C_MODE_END
#ifdef __cplusplus #endif /* _my_stacktrace_h_ */
}
#endif
...@@ -185,8 +185,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ...@@ -185,8 +185,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc ../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc ../sql/partition_info.cc ../sql/sql_connect.cc
../sql/scheduler.cc ../sql/stacktrace.c ../sql/scheduler.cc ../sql/event_parse_data.cc
../sql/event_parse_data.cc
${GEN_SOURCES} ${GEN_SOURCES}
${LIB_SOURCES}) ${LIB_SOURCES})
......
...@@ -69,7 +69,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ...@@ -69,7 +69,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sql_select.cc sql_do.cc sql_show.cc set_var.cc \ sql_select.cc sql_do.cc sql_show.cc set_var.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ unireg.cc uniques.cc sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
......
...@@ -79,6 +79,15 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, ...@@ -79,6 +79,15 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
my_bool result= 1; my_bool result= 1;
THD *thd=(THD *) mysql->thd; THD *thd=(THD *) mysql->thd;
NET *net= &mysql->net; NET *net= &mysql->net;
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
if (!thd)
{
/* Do "reconnect" if possible */
if (mysql_reconnect(mysql) || stmt_skip)
return 1;
thd= (THD *) mysql->thd;
}
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query(); thd->profiling.start_new_query();
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# # # #
############################################################################### ###############################################################################
--source include/not_embedded.inc
################################################################ ################################################################
# sql_low_priority_updates was renamed to low_priority_updates # # sql_low_priority_updates was renamed to low_priority_updates #
......
...@@ -39,7 +39,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ ...@@ -39,7 +39,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c) thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c)
......
...@@ -51,7 +51,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ ...@@ -51,7 +51,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_netware.c my_largepage.c \ my_handler.c my_netware.c my_largepage.c \
my_memmem.c \ my_memmem.c stacktrace.c \
my_windac.c my_access.c base64.c my_libwrap.c my_windac.c my_access.c base64.c my_libwrap.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c \ thr_mutex.c thr_rwlock.c \
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#define DONT_DEFINE_VOID 1 #define DONT_DEFINE_VOID 1
#include <my_global.h> #include <my_global.h>
#include "stacktrace.h" #include <my_stacktrace.h>
#ifndef __WIN__ #ifndef __WIN__
#include <signal.h> #include <signal.h>
...@@ -33,16 +33,22 @@ ...@@ -33,16 +33,22 @@
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
char *heap_start; static char *heap_start;
extern char *__bss_start;
void safe_print_str(const char* name, const char* val, int max_len) void my_init_stacktrace()
{
heap_start = (char*) &__bss_start;
}
void my_safe_print_str(const char* name, const char* val, int max_len)
{ {
char *heap_end= (char*) sbrk(0); char *heap_end= (char*) sbrk(0);
fprintf(stderr, "%s at %p ", name, val); fprintf(stderr, "%s at %p ", name, val);
if (!PTR_SANE(val)) if (!PTR_SANE(val))
{ {
fprintf(stderr, " is invalid pointer\n"); fprintf(stderr, "is an invalid pointer\n");
return; return;
} }
...@@ -103,6 +109,12 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) ...@@ -103,6 +109,12 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
#endif /* defined(__alpha__) && defined(__GNUC__) */ #endif /* defined(__alpha__) && defined(__GNUC__) */
#if BACKTRACE_DEMANGLE #if BACKTRACE_DEMANGLE
char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status)
{
return NULL;
}
static void my_demangle_symbols(char **addrs, int n) static void my_demangle_symbols(char **addrs, int n)
{ {
int status, i; int status, i;
...@@ -158,7 +170,7 @@ static void backtrace_current_thread(void) ...@@ -158,7 +170,7 @@ static void backtrace_current_thread(void)
#endif #endif
void print_stacktrace(uchar* stack_bottom, ulong thread_stack) void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{ {
#if HAVE_BACKTRACE #if HAVE_BACKTRACE
backtrace_current_thread(); backtrace_current_thread();
...@@ -281,16 +293,7 @@ void print_stacktrace(uchar* stack_bottom, ulong thread_stack) ...@@ -281,16 +293,7 @@ void print_stacktrace(uchar* stack_bottom, ulong thread_stack)
#endif /* HAVE_STACKTRACE */ #endif /* HAVE_STACKTRACE */
/* Produce a core for the thread */ /* Produce a core for the thread */
void my_write_core(int sig)
#ifdef NOT_USED /* HAVE_LINUXTHREADS */
void write_core(int sig)
{
signal(sig, SIG_DFL);
if (fork() != 0) exit(1); /* Abort main program */
/* Core will be written at exit */
}
#else
void write_core(int sig)
{ {
signal(sig, SIG_DFL); signal(sig, SIG_DFL);
#ifdef HAVE_gcov #ifdef HAVE_gcov
...@@ -308,7 +311,7 @@ void write_core(int sig) ...@@ -308,7 +311,7 @@ void write_core(int sig)
sigsend(P_PID,P_MYID,sig); sigsend(P_PID,P_MYID,sig);
#endif #endif
} }
#endif
#else /* __WIN__*/ #else /* __WIN__*/
#include <dbghelp.h> #include <dbghelp.h>
...@@ -356,6 +359,10 @@ static EXCEPTION_POINTERS *exception_ptrs; ...@@ -356,6 +359,10 @@ static EXCEPTION_POINTERS *exception_ptrs;
#define MODULE64_SIZE_WINXP 576 #define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64 #define STACKWALK_MAX_FRAMES 64
void my_init_stacktrace()
{
}
/* /*
Dynamically load dbghelp functions Dynamically load dbghelp functions
*/ */
...@@ -395,7 +402,7 @@ BOOL init_dbghelp_functions() ...@@ -395,7 +402,7 @@ BOOL init_dbghelp_functions()
return rc; return rc;
} }
void set_exception_pointers(EXCEPTION_POINTERS *ep) void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
{ {
exception_ptrs = ep; exception_ptrs = ep;
} }
...@@ -405,7 +412,7 @@ void set_exception_pointers(EXCEPTION_POINTERS *ep) ...@@ -405,7 +412,7 @@ void set_exception_pointers(EXCEPTION_POINTERS *ep)
#define SYMOPT_NO_PROMPTS 0 #define SYMOPT_NO_PROMPTS 0
#endif #endif
void print_stacktrace(uchar* unused1, ulong unused2) void my_print_stacktrace(uchar* unused1, ulong unused2)
{ {
HANDLE hProcess= GetCurrentProcess(); HANDLE hProcess= GetCurrentProcess();
HANDLE hThread= GetCurrentThread(); HANDLE hThread= GetCurrentThread();
...@@ -513,7 +520,7 @@ void print_stacktrace(uchar* unused1, ulong unused2) ...@@ -513,7 +520,7 @@ void print_stacktrace(uchar* unused1, ulong unused2)
file name is constructed from executable name plus file name is constructed from executable name plus
".dmp" extension ".dmp" extension
*/ */
void write_core(int unused) void my_write_core(int unused)
{ {
char path[MAX_PATH]; char path[MAX_PATH];
char dump_fname[MAX_PATH]= "core.dmp"; char dump_fname[MAX_PATH]= "core.dmp";
...@@ -560,7 +567,7 @@ void write_core(int unused) ...@@ -560,7 +567,7 @@ void write_core(int unused)
} }
void safe_print_str(const char *name, const char *val, int len) void my_safe_print_str(const char *name, const char *val, int len)
{ {
fprintf(stderr,"%s at %p", name, val); fprintf(stderr,"%s at %p", name, val);
__try __try
......
...@@ -43,7 +43,7 @@ ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER) ...@@ -43,7 +43,7 @@ ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
ADD_EXECUTABLE(mysqld ADD_EXECUTABLE(mysqld
../sql-common/client.c derror.cc des_key_file.cc ../sql-common/client.c derror.cc des_key_file.cc
discover.cc ../libmysql/errmsg.c field.cc stacktrace.c stacktrace.h field_conv.cc discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
filesort.cc gstream.cc filesort.cc gstream.cc
ha_partition.cc ha_partition.cc
handler.cc hash_filo.cc hash_filo.h handler.cc hash_filo.cc hash_filo.h
......
...@@ -66,7 +66,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -66,7 +66,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_repl.h slave.h rpl_filter.h rpl_injector.h \ sql_repl.h slave.h rpl_filter.h rpl_injector.h \
log_event.h rpl_record.h \ log_event.h rpl_record.h \
log_event_old.h rpl_record_old.h \ log_event_old.h rpl_record_old.h \
stacktrace.h sql_sort.h sql_cache.h set_var.h \ sql_sort.h sql_cache.h set_var.h \
spatial.h gstream.h client_settings.h tzfile.h \ spatial.h gstream.h client_settings.h tzfile.h \
tztime.h my_decimal.h\ tztime.h my_decimal.h\
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
...@@ -110,7 +110,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ ...@@ -110,7 +110,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
rpl_reporting.cc \ rpl_reporting.cc \
sql_union.cc sql_derived.cc \ sql_union.cc sql_derived.cc \
sql_client.cc \ sql_client.cc \
stacktrace.c repl_failsafe.h repl_failsafe.cc \ repl_failsafe.h repl_failsafe.cc \
sql_olap.cc sql_view.cc \ sql_olap.cc sql_view.cc \
gstream.cc spatial.cc sql_help.cc sql_cursor.cc \ gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
tztime.cc my_decimal.cc\ tztime.cc my_decimal.cc\
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "sql_repl.h" #include "sql_repl.h"
#include "rpl_filter.h" #include "rpl_filter.h"
#include "repl_failsafe.h" #include "repl_failsafe.h"
#include "stacktrace.h" #include <my_stacktrace.h>
#include "mysqld_suffix.h" #include "mysqld_suffix.h"
#include "mysys_err.h" #include "mysys_err.h"
#include "events.h" #include "events.h"
...@@ -2049,7 +2049,7 @@ LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers) ...@@ -2049,7 +2049,7 @@ LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */ #endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
__try __try
{ {
set_exception_pointers(ex_pointers); my_set_exception_pointers(ex_pointers);
handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode); handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
} }
__except(EXCEPTION_EXECUTE_HANDLER) __except(EXCEPTION_EXECUTE_HANDLER)
...@@ -2432,7 +2432,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", ...@@ -2432,7 +2432,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
Attempting backtrace. You can use the following information to find out\n\ 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\ where mysqld died. If you see no messages after this, something went\n\
terribly wrong...\n"); terribly wrong...\n");
print_stacktrace(thd ? (uchar*) thd->thread_stack : (uchar*) 0, my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
my_thread_stack_size); my_thread_stack_size);
} }
if (thd) if (thd)
...@@ -2457,7 +2457,7 @@ terribly wrong...\n"); ...@@ -2457,7 +2457,7 @@ terribly wrong...\n");
} }
fprintf(stderr, "Trying to get some variables.\n\ fprintf(stderr, "Trying to get some variables.\n\
Some pointers may be invalid and cause the dump to abort...\n"); Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024); my_safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
fprintf(stderr, "thd->killed=%s\n", kreason); fprintf(stderr, "thd->killed=%s\n", kreason);
} }
...@@ -2504,7 +2504,7 @@ bugs.\n"); ...@@ -2504,7 +2504,7 @@ bugs.\n");
{ {
fprintf(stderr, "Writing a core file\n"); fprintf(stderr, "Writing a core file\n");
fflush(stderr); fflush(stderr);
write_core(sig); my_write_core(sig);
} }
#endif #endif
...@@ -2538,7 +2538,7 @@ static void init_signals(void) ...@@ -2538,7 +2538,7 @@ static void init_signals(void)
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
init_stacktrace(); my_init_stacktrace();
#if defined(__amiga__) #if defined(__amiga__)
sa.sa_handler=(void(*)())handle_segfault; sa.sa_handler=(void(*)())handle_segfault;
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment