diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2018-06-23 09:47:18 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2018-06-25 13:28:09 +0200 |
commit | 46fc864b90228e007e13fbd166674309d51bf955 (patch) | |
tree | c36654819914b9662db193a642feea71cc6a396e | |
parent | 88aaf590ac9fa8c8030a5831cebd867a7f35478f (diff) | |
download | mariadb-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.txt | 1 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 17 | ||||
-rw-r--r-- | sql/net_serv.cc | 6 | ||||
-rw-r--r-- | unittest/embedded/CMakeLists.txt | 20 | ||||
-rw-r--r-- | unittest/embedded/test-connect.cc | 78 |
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; + +} |