Commit 93efbc39 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-22214 mariadbd.exe calls function mysqld.exe, and crashes

Stop linking plugins to the server executable on Windows.
Instead, extract whole server functionality into a large DLL, called
server.dll. Link both plugins, and small server "stub" exe to it.

This eliminates plugin dependency on the name of the server executable.
It also reduces the size of the packages (since tiny mysqld.exe
and mariadbd.exe are now both linked to one big DLL)

Also, simplify the functionality of exporing all symbols from selected
static libraries. Rely on WINDOWS_EXPORT_ALL_SYMBOLS, rather than old
self-backed solution.

fix compile error

replace GetProcAddress(GetModuleHandle(NULL), "variable_name")
for server exported data with actual variable names.

Runtime loading was never required,was error prone
, since symbols could be missing at runtime, and now it actually failed,
because we do not export symbols from executable anymore, but from a shared
library

This did require a MYSQL_PLUGIN_IMPORT decoration for the plugin,
but made the code more straightforward, and avoids missing symbols at
runtime (as mentioned before).

The audit plugin is still doing some dynamic loading, as it aims to work
cross-version. Now it won't work cross-version on Windows, as it already
uses some symbols that are *not* dynamically loaded, e.g fn_format
and those symbols now exported from server.dll , when earlier they were
exported by mysqld.exe

Windows, fixes for storage engine plugin loading
after various rebranding stuff

Create server.dll containing functionality of the whole server
make mariadbd.exe/mysqld.exe a stub that is only  calling mysqld_main()

fix build
parent 38f7dbec
......@@ -78,7 +78,10 @@ DYNAMIC_ARRAY binlog_events; // Storing the events output string
DYNAMIC_ARRAY events_in_stmt; // Storing the events that in one statement
String stop_event_string; // Storing the STOP_EVENT output string
extern "C" {
char server_version[SERVER_VERSION_LENGTH];
}
ulong server_id = 0;
// needed by net_serv.c
......
......@@ -38,7 +38,8 @@ FUNCTION (INSTALL_DEBUG_SYMBOLS)
ENDIF()
set(comp "")
IF((target STREQUAL "mariadbd"))
IF(target STREQUAL "server"
OR target STREQUAL "mariadbd")
SET(comp Server)
ENDIF()
......
......@@ -218,8 +218,7 @@ MACRO(MYSQL_ADD_PLUGIN)
# an additional dependency.
IF(ARG_RECOMPILE_FOR_EMBEDDED OR ARG_STORAGE_ENGINE)
IF(MSVC)
ADD_DEPENDENCIES(${target} gen_mysqld_lib)
TARGET_LINK_LIBRARIES(${target} mysqld_import_lib)
TARGET_LINK_LIBRARIES(${target} server)
ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES (${target} mariadbd)
ENDIF()
......
......@@ -1158,7 +1158,7 @@ extern struct charset_info_st my_charset_utf32_unicode_ci;
extern struct charset_info_st my_charset_utf32_unicode_nopad_ci;
extern struct charset_info_st my_charset_utf32_nopad_bin;
extern struct charset_info_st my_charset_utf32_general_nopad_ci;
extern struct charset_info_st my_charset_utf8mb3_bin;
extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_utf8mb3_bin;
extern struct charset_info_st my_charset_utf8mb3_nopad_bin;
extern struct charset_info_st my_charset_utf8mb3_general_nopad_ci;
extern struct charset_info_st my_charset_utf8mb3_general_mysql500_ci;
......
......@@ -131,7 +131,7 @@ extern int (*dbug_sanity)(void);
#define DBUG_ABORT() (_db_flush_(),\
(void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\
(void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\
_exit(3))
TerminateProcess(GetCurrentProcess(),3))
#endif
/*
......
......@@ -20,9 +20,9 @@
C_MODE_START
extern const char *my_defaults_extra_file;
extern MYSQL_PLUGIN_IMPORT const char *my_defaults_extra_file;
extern const char *my_defaults_group_suffix;
extern const char *my_defaults_file;
extern MYSQL_PLUGIN_IMPORT const char *my_defaults_file;
extern my_bool my_defaults_mark_files;
extern int get_defaults_options(char **argv);
......
......@@ -91,13 +91,7 @@ static int locale_info_plugin_init_locales(void *p)
schema->fields_info= Show::locale_info_locale_fields_info;
schema->fill_table= locale_info_fill_table_locale;
#if defined(_WIN64)
locale_list = (MY_LOCALE **)GetProcAddress(GetModuleHandle(NULL), "?my_locales@@3PAPEAVMY_LOCALE@@A");
#elif defined(_WIN32)
locale_list = (MY_LOCALE **)GetProcAddress(GetModuleHandle(NULL), "?my_locales@@3PAPAVMY_LOCALE@@A");
#else
locale_list = my_locales;
#endif
return 0;
}
......
......@@ -283,13 +283,7 @@ static int qc_info_plugin_init(void *p)
schema->fields_info= Show::qc_info_fields;
schema->fill_table= qc_info_fill_table;
#ifdef _WIN32
qc = (Accessible_Query_Cache *)
GetProcAddress(GetModuleHandle(NULL), "?query_cache@@3VQuery_cache@@A");
#else
qc = (Accessible_Query_Cache *)&query_cache;
#endif
return qc == 0;
}
......
......@@ -276,7 +276,7 @@ static my_off_t loc_tell(File fd)
#endif /*WIN32*/
extern char server_version[];
extern MYSQL_PLUGIN_IMPORT char server_version[];
static const char *serv_ver= NULL;
static int started_mysql= 0;
static int mysql_57_started= 0;
......@@ -2373,31 +2373,37 @@ typedef struct loc_system_variables
static int init_done= 0;
static void* find_sym(const char *sym)
{
#ifdef _WIN32
return GetProcAddress(GetModuleHandle("server.dll"),sym);
#else
return dlsym(RTLD_DEFAULT, sym);
#endif
}
static int server_audit_init(void *p __attribute__((unused)))
{
if (!serv_ver)
{
#ifdef _WIN32
serv_ver= (const char *) GetProcAddress(0, "server_version");
#else
serv_ver= server_version;
#endif /*_WIN32*/
serv_ver= find_sym("server_version");
}
if (!mysql_57_started)
{
const void *my_hash_init_ptr= dlsym(RTLD_DEFAULT, "_my_hash_init");
const void *my_hash_init_ptr= find_sym("_my_hash_init");
if (!my_hash_init_ptr)
{
maria_above_5= 1;
my_hash_init_ptr= dlsym(RTLD_DEFAULT, "my_hash_init2");
my_hash_init_ptr= find_sym("my_hash_init2");
}
if (!my_hash_init_ptr)
return 1;
}
if(!(int_mysql_data_home= dlsym(RTLD_DEFAULT, "mysql_data_home")))
if(!(int_mysql_data_home= find_sym("mysql_data_home")))
{
if(!(int_mysql_data_home= dlsym(RTLD_DEFAULT, "?mysql_data_home@@3PADA")))
if(!(int_mysql_data_home= find_sym("?mysql_data_home@@3PADA")))
int_mysql_data_home= &default_home;
}
......@@ -2929,7 +2935,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
if (fdwReason != DLL_PROCESS_ATTACH)
return 1;
serv_ver= (const char *) GetProcAddress(0, "server_version");
serv_ver= server_version;
#else
void __attribute__ ((constructor)) audit_plugin_so_init(void)
{
......
......@@ -179,7 +179,7 @@ IF ((CMAKE_SYSTEM_NAME MATCHES "Linux" OR
ENDIF()
IF(WIN32)
SET(SQL_SOURCE ${SQL_SOURCE} handle_connections_win.cc)
SET(SQL_SOURCE ${SQL_SOURCE} handle_connections_win.cc nt_servc.cc)
ENDIF()
MYSQL_ADD_PLUGIN(partition ha_partition.cc STORAGE_ENGINE DEFAULT STATIC_ONLY
......@@ -208,86 +208,44 @@ FOREACH(se aria partition perfschema sql_sequence wsrep)
ENDFOREACH()
IF(WIN32)
SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc)
TARGET_LINK_LIBRARIES(sql psapi)
SET(MYSQLD_SOURCE main.cc message.rc)
ELSE()
SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL})
ENDIF()
IF(MSVC)
SET(libs_to_export_symbols sql mysys dbug strings)
# Create shared library of already compiled object
# Export all symbols from selected libraries, to be used
# by plugins
ADD_LIBRARY(server SHARED
$<TARGET_OBJECTS:sql>
$<TARGET_OBJECTS:mysys>
$<TARGET_OBJECTS:dbug>
$<TARGET_OBJECTS:strings>
${PROJECT_BINARY_DIR}/versioninfo_dll.rc
)
IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
# mysqld.exe must to export symbols from some specific libs.
# These symbols are used by dynamic plugins, that "link" to mysqld.
#
# To do that, we
#
# 1. Generate mysqld_lib.def text file with all symbols from static
# libraries mysys, dbug, strings, sql.
# 2. Then we call
# lib.exe /DEF:mysqld_lib.def ...
# to create import library mysqld_lib.lib and export library mysqld_lib.exp
# 3. mysqld.exe links with mysqld_lib.exp (exporting symbols)
# 4. plugins link with mysqld_lib.lib (importing symbols)
#
# We do not not regenerate .def, .lib and .exp
# without necessity.E.g source modifications, that do not
# change list of exported symbols, will not result in a relink for plugins.
SET(MYSQLD_DEF ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib${CMAKE_CFG_INTDIR}.def)
SET(MYSQLD_EXP ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib${CMAKE_CFG_INTDIR}.exp)
SET(MYSQLD_LIB ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib${CMAKE_CFG_INTDIR}.lib)
SET(MYSQLD_CORELIBS sql mysys dbug strings)
FOREACH (CORELIB ${MYSQLD_CORELIBS})
SET (LIB_LOCATIONS ${LIB_LOCATIONS} $<TARGET_FILE:${CORELIB}>)
ENDFOREACH (CORELIB)
SET(_PLATFORM x86)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(_PLATFORM x64)
ENDIF()
# Create a cmake script to generate import and export libs
# from a .def file
SET(CMAKE_CONFIGURABLE_FILE_CONTENT "
IF ((mysqld_lib\${CFG}.def IS_NEWER_THAN mysqld_lib\${CFG}.lib) OR
(mysqld_lib\${CFG}.def IS_NEWER_THAN mysqld_lib\${CFG}.exp))
FILE(REMOVE mysqld_lib\${CFG}.lib mysqld_lib\${CFG}.exp)
SET(ENV{VS_UNICODE_OUTPUT})
EXECUTE_PROCESS (
COMMAND \"${CMAKE_LINKER}\" /lib /NAME:mysqld.exe \"/DEF:${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib\${CFG}.def\" /MACHINE:${_PLATFORM}
RESULT_VARIABLE ret)
IF(NOT ret EQUAL 0)
MESSAGE(FATAL_ERROR \"process failed ret=\${ret}\")
ENDIF()
# We need to add all dependencies of sql/mysys/dbug/strings
# to link the shared library
SET(all_deps)
FOREACH(lib ${libs_to_export_symbols})
GET_TARGET_PROPERTY(deps ${lib} LINK_LIBRARIES)
IF(deps)
LIST(APPEND all_deps ${deps})
ENDIF()
")
CONFIGURE_FILE(
${PROJECT_SOURCE_DIR}/cmake/configurable_file_content.in
make_mysqld_lib.cmake
@ONLY)
IF(CMAKE_VERSION VERSION_GREATER "3.2.0")
SET(MYSQLD_LIB_BYPRODUCTS BYPRODUCTS ${MYSQLD_DEF} ${MYSQLD_LIB} ${MYSQLD_EXP})
ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.stamp
${MYSQLD_LIB_BYPRODUCTS}
COMMENT "Generating ${MYSQLD_DEF}, ${MYSQLD_LIB}, ${MYSQLD_EXP}"
COMMAND cscript //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
${_PLATFORM} /forLib ${LIB_LOCATIONS} > ${MYSQLD_DEF}.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${MYSQLD_DEF}.tmp ${MYSQLD_DEF}
COMMAND ${CMAKE_COMMAND} -E remove ${MYSQLD_DEF}.tmp
COMMAND ${CMAKE_COMMAND} "-DCFG=${CMAKE_CFG_INTDIR}" -P make_mysqld_lib.cmake
COMMAND ${CMAKE_COMMAND} -E touch mysqld_lib.stamp
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${MYSQLD_CORELIBS}
ENDFOREACH()
LIST(REMOVE_DUPLICATES all_deps)
FOREACH(lib ${libs_to_export_symbols})
LIST(REMOVE_ITEM all_deps ${lib})
ENDFOREACH()
TARGET_LINK_LIBRARIES(server
${all_deps}
sql_builtins
)
ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.stamp)
ADD_LIBRARY(mysqld_import_lib UNKNOWN IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB})
SET_TARGET_PROPERTIES(server PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
MYSQL_INSTALL_TARGETS(server DESTINATION ${INSTALL_BINDIR} COMPONENT Server)
ENDIF()
ADD_LIBRARY(sql_builtins STATIC ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc)
......@@ -311,17 +269,13 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS)
IF(NOT mysqld_link_flags)
SET(mysqld_link_flags)
ENDIF()
IF (MINGW OR CYGWIN)
SET_TARGET_PROPERTIES(mariadbd PROPERTIES LINK_FLAGS "${mysqld_link_flags} -Wl,--export-all-symbols")
ENDIF()
IF(MSVC)
SET_TARGET_PROPERTIES(mariadbd PROPERTIES LINK_FLAGS "${mysqld_link_flags} \"${MYSQLD_EXP}\"")
ADD_DEPENDENCIES(mariadbd gen_mysqld_lib)
ENDIF()
ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS)
TARGET_LINK_LIBRARIES(mariadbd LINK_PRIVATE sql sql_builtins)
IF(MSVC)
TARGET_LINK_LIBRARIES(mariadbd server)
ELSE()
TARGET_LINK_LIBRARIES(mariadbd LINK_PRIVATE sql sql_builtins)
ENDIF()
# Provide plugins with minimal set of libraries
SET(INTERFACE_LIBS ${LIBRT})
......@@ -461,7 +415,7 @@ IF(TARGET mariadbd AND NOT CMAKE_CROSSCOMPILING)
ENDIF()
ADD_CUSTOM_TARGET(initial_database
${ALL_ON_WINDOWS}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
)
ENDIF()
......
......@@ -587,7 +587,10 @@ DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
const char *mysql_real_data_home_ptr= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH], *server_version_ptr;
extern "C" {
char server_version[SERVER_VERSION_LENGTH];
}
char *server_version_ptr;
bool using_custom_server_version= false;
char *mysqld_unix_port, *opt_mysql_tmpdir;
ulong thread_handling;
......
......@@ -117,7 +117,7 @@ extern bool opt_skip_name_resolve;
extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern my_bool debug_assert_on_not_freed_memory;
extern bool volatile abort_loop;
extern MYSQL_PLUGIN_IMPORT bool volatile abort_loop;
extern Atomic_counter<uint> connection_count;
extern my_bool opt_safe_user_create;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
......@@ -143,7 +143,7 @@ extern ulong use_stat_tables;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
extern const char *shared_memory_base_name;
extern char *mysqld_unix_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
extern my_bool opt_enable_shared_memory;
extern ulong opt_replicate_events_marked_for_skip;
extern char *default_tz_name;
......@@ -168,7 +168,8 @@ extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
extern my_bool relay_log_recovery;
extern uint select_errors,ha_open_options;
extern ulonglong test_flags;
extern uint protocol_version, mysqld_port, dropping_tables;
extern uint protocol_version, dropping_tables;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern ulong delay_key_write_options;
extern char *opt_logname, *opt_slow_logname, *opt_bin_logname,
*opt_relay_logname;
......@@ -281,7 +282,8 @@ extern handlerton *heap_hton;
extern const char *load_default_groups[];
extern struct my_option my_long_options[];
int handle_early_options();
extern int mysqld_server_started, mysqld_server_initialized;
extern int MYSQL_PLUGIN_IMPORT mysqld_server_started;
extern int mysqld_server_initialized;
extern "C" MYSQL_PLUGIN_IMPORT int orig_argc;
extern "C" MYSQL_PLUGIN_IMPORT char **orig_argv;
extern pthread_attr_t connection_attrib;
......@@ -752,8 +754,8 @@ extern mysql_mutex_t LOCK_start_thread;
extern char* des_key_file;
extern mysql_mutex_t LOCK_des_key_file;
#endif
extern mysql_mutex_t LOCK_server_started;
extern mysql_cond_t COND_server_started;
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_server_started;
extern MYSQL_PLUGIN_IMPORT mysql_cond_t COND_server_started;
extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern mysql_rwlock_t LOCK_ssl_refresh;
extern mysql_prlock_t LOCK_system_variables_hash;
......
......@@ -608,5 +608,5 @@ struct Query_cache_query_flags
#define query_cache_is_cacheable_query(L) 0
#endif /*HAVE_QUERY_CACHE*/
extern Query_cache query_cache;
extern MYSQL_PLUGIN_IMPORT Query_cache query_cache;
#endif
......@@ -66,7 +66,7 @@ class MY_LOCALE
/* Exported variables */
extern MY_LOCALE my_locale_en_US;
extern MY_LOCALE *my_locales[];
extern MYSQL_PLUGIN_IMPORT MY_LOCALE *my_locales[];
extern MY_LOCALE *my_default_lc_messages;
extern MY_LOCALE *my_default_lc_time_names;
......
......@@ -73,7 +73,7 @@ class Time_zone: public Sql_alloc
};
extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
extern MYSQL_PLUGIN_IMPORT Time_zone * my_tz_SYSTEM;
extern Time_zone * my_tz_OFFSET0;
extern Time_zone * my_tz_find(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
......
......@@ -6976,62 +6976,6 @@ int spider_db_init(
memset(&spider_alloc_mem_count, 0, sizeof(spider_alloc_mem_count));
memset(&spider_free_mem_count, 0, sizeof(spider_free_mem_count));
#ifdef _WIN32
HMODULE current_module = GetModuleHandle(NULL);
#ifndef SPIDER_HAS_NEXT_THREAD_ID
spd_db_att_thread_id = (ulong *)
GetProcAddress(current_module, "?thread_id@@3KA");
#endif
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef XID_CACHE_IS_SPLITTED
spd_db_att_xid_cache_split_num = (uint *)
GetProcAddress(current_module,
"?opt_xid_cache_split_num@@3IA");
spd_db_att_LOCK_xid_cache = *((pthread_mutex_t **)
GetProcAddress(current_module,
"?LOCK_xid_cache@@3PAUst_mysql_mutex@@A"));
spd_db_att_xid_cache = *((HASH **)
GetProcAddress(current_module, "?xid_cache@@3PAUst_hash@@A"));
#else
spd_db_att_LOCK_xid_cache = (pthread_mutex_t *)
#if MYSQL_VERSION_ID < 50500
GetProcAddress(current_module,
"?LOCK_xid_cache@@3U_RTL_CRITICAL_SECTION@@A");
#else
GetProcAddress(current_module,
"?LOCK_xid_cache@@3Ust_mysql_mutex@@A");
#endif
spd_db_att_xid_cache = (HASH *)
GetProcAddress(current_module, "?xid_cache@@3Ust_hash@@A");
#endif
#endif
spd_charset_utf8mb3_bin = (struct charset_info_st *)
GetProcAddress(current_module, "my_charset_utf8mb3_bin");
spd_defaults_extra_file = (const char **)
GetProcAddress(current_module, "my_defaults_extra_file");
spd_defaults_file = (const char **)
GetProcAddress(current_module, "my_defaults_file");
spd_mysqld_unix_port = (const char **)
GetProcAddress(current_module, "?mysqld_unix_port@@3PADA");
spd_mysqld_port = (uint *)
GetProcAddress(current_module, "?mysqld_port@@3IA");
spd_abort_loop = (bool volatile *)
GetProcAddress(current_module, "?abort_loop@@3_NC");
spd_tz_system = *(Time_zone **)
#ifdef _WIN64
GetProcAddress(current_module, "?my_tz_SYSTEM@@3PEAVTime_zone@@EA");
#else
GetProcAddress(current_module, "?my_tz_SYSTEM@@3PAVTime_zone@@A");
#endif
spd_mysqld_server_started = (int *)
GetProcAddress(current_module, "?mysqld_server_started@@3HA");
spd_LOCK_server_started = (pthread_mutex_t *)
GetProcAddress(current_module,
"?LOCK_server_started@@3Ust_mysql_mutex@@A");
spd_COND_server_started = (pthread_cond_t *)
GetProcAddress(current_module, "?COND_server_started@@3Ust_mysql_cond@@A");
#else
#ifndef SPIDER_HAS_NEXT_THREAD_ID
spd_db_att_thread_id = &thread_id;
#endif
......@@ -7056,7 +7000,6 @@ int spider_db_init(
spd_mysqld_server_started = &mysqld_server_started;
spd_LOCK_server_started = &LOCK_server_started;
spd_COND_server_started = &COND_server_started;
#endif
#ifdef HAVE_PSI_INTERFACE
init_spider_psi_keys();
......
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