summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2018-06-23 09:47:18 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2018-06-25 13:28:09 +0200
commit46fc864b90228e007e13fbd166674309d51bf955 (patch)
treec36654819914b9662db193a642feea71cc6a396e
parent88aaf590ac9fa8c8030a5831cebd867a7f35478f (diff)
downloadmariadb-git-46fc864b90228e007e13fbd166674309d51bf955.tar.gz
MDEV-16478: mysql_real_connect() from libmariadbd.so always crash
Returned accidentally removed undefinition of MYSQL_SERVER in net_serv.cc inside embedded server (embedded server uses real_net_read/write only as a client) Prevented attempt to clean up embedded server if it was not initialized
-rw-r--r--CMakeLists.txt1
-rw-r--r--libmysqld/lib_sql.cc17
-rw-r--r--sql/net_serv.cc6
-rw-r--r--unittest/embedded/CMakeLists.txt20
-rw-r--r--unittest/embedded/test-connect.cc78
5 files changed, 118 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 76b0817f8c7..d1595aa77b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -398,6 +398,7 @@ IF(NOT WITHOUT_SERVER)
IF(WITH_EMBEDDED_SERVER)
ADD_SUBDIRECTORY(libmysqld)
ADD_SUBDIRECTORY(libmysqld/examples)
+ ADD_SUBDIRECTORY(unittest/embedded)
ENDIF(WITH_EMBEDDED_SERVER)
IF(WITH_WSREP)
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index d32a96255b9..dd111d1b224 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -55,6 +55,9 @@ extern "C" void unireg_clear(int exit_code)
DBUG_VOID_RETURN;
}
+
+static my_bool mysql_embedded_init= 0;
+
/*
Wrapper error handler for embedded server to call client/server error
handler based on whether thread is in client/server context
@@ -518,6 +521,8 @@ int init_embedded_server(int argc, char **argv, char **groups)
const char *fake_groups[] = { "server", "embedded", 0 };
my_bool acl_error;
+ DBUG_ASSERT(mysql_embedded_init == 0);
+
if (my_thread_init())
return 1;
@@ -637,15 +642,19 @@ int init_embedded_server(int argc, char **argv, char **groups)
}
execute_ddl_log_recovery();
+ mysql_embedded_init= 1;
return 0;
}
void end_embedded_server()
{
- my_free(copy_arguments_ptr);
- copy_arguments_ptr=0;
- clean_up(0);
- clean_up_mutexes();
+ if (mysql_embedded_init)
+ {
+ my_free(copy_arguments_ptr);
+ copy_arguments_ptr=0;
+ clean_up(0);
+ clean_up_mutexes();
+ }
}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 0d3aa12465d..576ef5009b5 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -47,6 +47,12 @@
#include "probes_mysql.h"
#include "proxy_protocol.h"
+#ifdef EMBEDDED_LIBRARY
+#undef MYSQL_SERVER
+#undef MYSQL_CLIENT
+#define MYSQL_CLIENT
+#endif /*EMBEDDED_LIBRARY */
+
/*
to reduce the number of ifdef's in the code
*/
diff --git a/unittest/embedded/CMakeLists.txt b/unittest/embedded/CMakeLists.txt
new file mode 100644
index 00000000000..cf48550c377
--- /dev/null
+++ b/unittest/embedded/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/libmysqld/include
+ ${PCRE_INCLUDES}
+ ${CMAKE_SOURCE_DIR}/sql
+ ${MY_READLINE_INCLUDE_DIR}
+ )
+
+
+ADD_DEFINITIONS(-DEMBEDDED_LIBRARY -UMYSQL_CLIENT)
+
+
+MYSQL_ADD_EXECUTABLE(test-connect-t test-connect.cc
+ COMPONENT Test)
+TARGET_LINK_LIBRARIES(test-connect-t mysqlserver )
+MY_ADD_TEST(test-connect)
+
+IF(UNIX)
+SET_TARGET_PROPERTIES(test-connect-t PROPERTIES ENABLE_EXPORTS TRUE)
+ENDIF()
diff --git a/unittest/embedded/test-connect.cc b/unittest/embedded/test-connect.cc
new file mode 100644
index 00000000000..cd122286130
--- /dev/null
+++ b/unittest/embedded/test-connect.cc
@@ -0,0 +1,78 @@
+#include <mysql.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int get_evar(char **hostname, char **port, char** username, char ** password)
+{
+
+ if (!((*hostname)= getenv("MYSQL_TEST_HOST")))
+ (*hostname)= (char *)"127.0.0.1";
+
+ if (!((*port)= getenv("MASTER_MYPORT")))
+ {
+ if (!((*port)= getenv("MYSQL_TEST_PORT")))
+ return 1;
+ }
+
+ if (!((*username)= getenv("MYSQL_TEST_USER")))
+ (*username)= (char *)"root";
+
+ if (!((*password)= getenv("MYSQL_TEST_PASSWD")))
+ (*password)= (char *)"";
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ MYSQL *mysql;
+ char *host;
+ char *user;
+ char *passwd;
+ char *porta;
+ unsigned int port;
+
+ if (get_evar(&host, &porta, &user, &passwd))
+ {
+ printf("set environment variable MASTER_MYPORT\n");
+ return 1;
+ }
+
+ port = atoi(porta);
+
+ mysql_thread_init();
+
+ if (mysql_server_init(-1, NULL, NULL) != 0) {
+ printf("mysql_library_init failed");
+ return 1;
+ }
+
+
+ mysql = mysql_init(NULL);
+
+ if (!mysql) {
+ printf("mysql_init failed");
+ return 1;
+ }
+
+ if (mysql_options(mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL) != 0) {
+ printf("mysql_options MYSQL_OPT_USE_REMOTE_CONNECTION failed: %s\n", mysql_error(mysql));
+ return 1;
+ }
+
+ if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4") != 0) {
+ printf("mysql_options MYSQL_SET_CHARSET_NAME utf8mb4 failed: %s\n", mysql_error(mysql));
+ return 1;
+ }
+
+ if (!mysql_real_connect(mysql, host, user, passwd, NULL, port, NULL, CLIENT_FOUND_ROWS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS)) {
+ printf("mysql_real_connect failed: %s\n", mysql_error(mysql));
+ return 1;
+ }
+ mysql_close(mysql);
+ mysql_thread_end();
+ mysql_library_end();
+
+ return 0;
+
+}