Commit 30bd1d7c authored by Davi Arnaut's avatar Davi Arnaut
Browse files

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.
parent c20188e0
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")

# 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.

SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
@@ -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)
TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)

ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c
               ../mysys/my_copy.c ../mysys/my_mkdir.c)
TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32)
ADD_EXECUTABLE(mysqltest mysqltest.c)
SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)

ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
+7 −5
Original line number Diff line number Diff line
@@ -86,11 +86,13 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
				$(LIBMYSQLCLIENT_LA) \
				$(top_builddir)/mysys/libmysys.a

mysqltest_SOURCES=		mysqltest.c \
				$(top_srcdir)/mysys/my_getsystime.c \
				$(top_srcdir)/mysys/my_copy.c \
                                $(top_srcdir)/mysys/my_mkdir.c
mysqltest_LDADD =		$(top_builddir)/regex/libregex.a $(LDADD)
mysqltest_SOURCES=		mysqltest.c
mysqltest_CFLAGS=		-DTHREAD -UUNDEF_THREADS_HACK
mysqltest_LDADD =		$(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
				@CLIENT_EXTRA_LDFLAGS@ \
				$(LIBMYSQLCLIENT_LA) \
				$(top_builddir)/mysys/libmysys.a \
				$(top_builddir)/regex/libregex.a

mysql_upgrade_SOURCES=          mysql_upgrade.c \
                                $(top_srcdir)/mysys/my_getpagesize.c
+92 −0
Original line number Diff line number Diff line
@@ -48,7 +48,14 @@
#ifdef __WIN__
#include <direct.h>
#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 */
#if MYSQL_VERSION_ID < 50000
@@ -214,6 +221,7 @@ struct st_connection
  /* Used when creating views and sp, to avoid implicit commit */
  MYSQL* util_mysql;
  char *name;
  size_t name_len;
  MYSQL_STMT* stmt;

#ifdef EMBEDDED_LIBRARY
@@ -4436,6 +4444,7 @@ void do_connect(struct st_command *command)
                        ds_connection_name.str));
    if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
      die("Out of memory");
    con_slot->name_len= strlen(con_slot->name);
    cur_con= con_slot;
    
    if (con_slot == next_con)
@@ -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)
{
  struct st_command *command;
@@ -6851,6 +6941,8 @@ int main(int argc, char **argv)
  save_file[0]= 0;
  TMPDIR[0]= 0;

  init_signal_handling();

  /* Init expected errors */
  memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));

+11 −1
Original line number Diff line number Diff line
@@ -2341,10 +2341,20 @@ then
fi
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_CPLUSPLUS
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>], [
  char *foo= 0; int bar= 0;
  foo= abi::__cxa_demangle(foo, foo, 0, &bar);
+1 −1
Original line number Diff line number Diff line
@@ -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 \
			my_vle.h my_user.h my_atomic.h atomic/nolock.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
CLEANFILES =            $(BUILT_SOURCES) readline openssl
Loading