Bug #27801 | mysqld got signal 11 and crashes during mysql_real_connect call | ||
---|---|---|---|
Submitted: | 13 Apr 2007 4:19 | Modified: | 11 May 2007 14:24 |
Reporter: | Dmitriy E | Email Updates: | |
Status: | Won't fix | Impact on me: | |
Category: | MySQL Server: C API (client library) | Severity: | S1 (Critical) |
Version: | 5.0.42-BK, 5.0.37, 5.0.27 | OS: | Linux |
Assigned to: | Antony Curtis | CPU Architecture: | Any |
Tags: | crash, linux, mysql_real_connect, so, udf |
[13 Apr 2007 4:19]
Dmitriy E
[13 Apr 2007 6:29]
Valeriy Kravchuk
Thank you for a problem report. Please, try to repeat with a newer version, 5.0.37. In case of the same problem, please, send the resolved stack trace and exact command line used for compilation.
[13 Apr 2007 11:22]
Dmitriy E
Hi, Thanks for looking into this! We are trying 5.0.37 and let you know soon if it works or not, but regardless of the result we need a solution for most 5.x.x versions, not just an unknown fix for a single version. We checked lots of combinations of how to call mysql_init and mysql_real_connect just to see where the bug could be hidden. It appears that mysql_init() always works ok. On the other hand, mysql_real_connect() fails regardless of what we specify for the server localhost, or NULL. However, if we specify a specific port number or socket file path, mysql_real_connect() establishes the connection but then immediately crashes with segmentation fault. If we specify wrong parameters for the connection, it does not connect and it does not crash. In the debuger we see the following trace: thd_increment_bytes_received <- net_real_write my_net_read cli_safe_read mysql_real_connect Then the connection thread crashes with signal 1. Finally mysql exits. Hope this could help you identity the root cause of the problem. Is there anything else specific to this issue that you want us to try, other then to try?
[13 Apr 2007 11:28]
Dmitriy E
in the last message, ending "other then to try" wasn't intended for input
[16 Apr 2007 12:59]
Dmitriy E
Any updates on this issue? Is there anybody looking into this?
[16 Apr 2007 19:57]
Valeriy Kravchuk
Note that if you need solutions for different versions and/or in any predictable time ("ASAP") you have to become a customer and got a support contract. I am not sure that connecting to server from UDF is really supported and should work in general case. Please, send the resolved stack trace: 0x8164f80 0x815aaf6 0x815db05 0x815de53 0x8254178 0x82557ec 0xd59883 0xde73b6 0x1c933e
[16 Apr 2007 20:20]
Dmitriy E
Hi, We actually have MySQL network partner status. Hope this makes us eligible to submit bug reports and expect some response. Please note that I don't expect this issue to be fixed ASAP, if it is an issue in MySQL, but I do expect that somebody can advise us on how to deal with it and the suggested solution is usable. Thanks in advance for looking into this. We will provide the requested stack trace. Dmitriy
[17 Apr 2007 12:17]
Dmitriy E
Here is the requested stack trace. Hope this can help you to figure out the root cause of the problem. 0x8164f80 handle_segfault + 416 0x815aaf6 thd_increment_bytes_received + 22 0x815db05 _Z12my_real_readP6st_netPm + 453 0x815de53 my_net_read + 515 0x8254178 cli_safe_read + 296 0x82557ec mysql_real_connect + 940 0xd59883 (?) 0xde73b6 (?) 0x1c933e (?)
[17 Apr 2007 12:20]
Dmitriy E
The stack trace I posted earlier is for version 5.0.27. Here is a stack trace for version 5.0.37. As you can see, the result is the same; it crashes in the same place. 0x81698b0 handle_segfault + 416 0x815efb6 thd_increment_bytes_received + 22 0x8162035 _Z12my_real_readP6st_netPm + 453 0x8162383 my_net_read + 515 0x82606c8 cli_safe_read + 296 0x8261de5 mysql_real_connect + 997 0x5b293d (?) 0xde73b6 (?) 0x1c933e (?)
[17 Apr 2007 13:42]
Valeriy Kravchuk
In your test case you have: #include "udf.h" Please, send content of that file. May I just remove that #include? Please, send also exact command line used to compile myfile.so.
[29 Apr 2007 8:23]
Valeriy Kravchuk
I've got exactly the same results with latest 5.0.42-BK. Even if it (inability to handle "UDFs" in .so libraries like this) is intended behaviour without workarounds, server crash is still a bug, I think. openxs@suse:~/dbs/5.0> bin/resolve_stack_dump -s /tmp/mysqld5.sym 16019_1.stack 0x81bbeb6 handle_segfault + 646 0x81a8298 thd_increment_bytes_received + 24 0x81b09fb _Z12my_real_readP6st_netPm + 123 0x81b0fcb my_net_read + 331 0x82f500d cli_safe_read + 269 0x82f5cfc mysql_real_connect + 828 0x42896803 _end + 974903663 0x40050aa7 _end + 932674579 0x40247c2e _end + 934735258 openxs@suse:~/dbs/5.0> uname -a Linux suse 2.6.11.4-20a-default #1 Wed Mar 23 21:52:37 UTC 2005 i686 i686 i386 G NU/Linux openxs@suse:~/dbs/5.0> cat udf.c #include <pthread.h> #include "mysql.h" /*#include "udf.h"*/ void CreateThread(void* entryPoint, void *data){ pthread_t* threadId = (pthread_t*) malloc(sizeof(pthread_t)); int rc = 0; pthread_attr_t attr; if (entryPoint == NULL){ return; } rc = pthread_attr_init(&attr); if (rc) { return ; } rc = pthread_create(threadId, &attr, (void*(*)(void*))entryPoint, data); if(rc){ return ; } return; } void ThreadFunc(void *data) { MYSQL * mysqlStruct = NULL; mysqlStruct = mysql_init(NULL); mysqlStruct = mysql_real_connect(mysqlStruct, "localhost", "root", "", "mysql", 3306, NULL, 0); } void __attribute__ ((constructor)) dl_init(void){ CreateThread((void*)ThreadFunc,NULL); } void __attribute__ ((destructor)) dl_deinit(void){} double mytest(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error){retur n 0.;} my_bool mytest_init(UDF_INIT *initid, UDF_ARGS *args, char *message){return 0;} void mytest_deinit(UDF_INIT *initid){} Compiled as: openxs@suse:~/dbs/5.0> CFG=/home/openxs/dbs/5.0/bin/mysql_config + CFG=/home/openxs/dbs/5.0/bin/mysql_config openxs@suse:~/dbs/5.0> gcc -shared -o udf.so `$CFG --cflags` udf.c `$CFG --libs ` ++ /home/openxs/dbs/5.0/bin/mysql_config --cflags ++ /home/openxs/dbs/5.0/bin/mysql_config --libs + gcc -shared -o udf.so -I/home/openxs/dbs/5.0/include/mysql udf.c -L/home/openx s/dbs/5.0/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm Function mytest created as: CREATE FUNCTION mytest RETURNS REAL SONAME 'udf.so'; Execution of statement above immediately leads to crash (and infinite restarts + crashed, in case of mysqld_safe used) with resolved stack trace above.
[29 Apr 2007 10:14]
Valeriy Kravchuk
Full trace from gdb based on core file created: (gdb) bt #0 0xffffe410 in ?? () #1 0x42c675ec in ?? () #2 0x0000000b in ?? () #3 0x00001de9 in ?? () #4 0x40053838 in pthread_kill () from /lib/tls/libpthread.so.0 #5 0x082f7533 in write_core () #6 0x081bc054 in handle_segfault () #7 <signal handler called> #8 0x081a8468 in thd_increment_bytes_received () #9 0x081b0bcb in my_real_read () #10 0x081b119b in my_net_read () #11 0x082f50ad in cli_safe_read () #12 0x082f5d9c in mysql_real_connect () #13 0x42896803 in ThreadFunc () from /home/openxs/dbs/5.0/udf.so #14 0x40050aa7 in pthread_create () from /lib/tls/libpthread.so.0 #15 0x40247c2e in clone () from /lib/tls/libc.so.6
[1 May 2007 23:19]
Calvin Sun
According to Kostja, it is a plugin problem.
[2 May 2007 0:11]
Antony Curtis
the internal mysqld version of 'libmysql' client lib works on different rules than the standard library we have for C clients. Expecting this code to work, which creates a thread not managed my mysqld and using mysqld internal funcs, even if they look like the mysql client libs... it is not going to work. I would personally say that this bug is not a bug.
[7 May 2007 18:14]
Valeriy Kravchuk
Note that the following code works as expected: openxs@suse:~/dbs/5.0> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd` openxs@suse:~/dbs/5.0> CFG=/home/openxs/dbs/5.0/bin/mysql_config openxs@suse:~/dbs/5.0> gcc -shared -o udf.so `$CFG --cflags` -DDEBUG udf4.c openxs@suse:~/dbs/5.0> bin/mysqld_safe --core-file --core-file-size=256000000 & [1] 3450 openxs@suse:~/dbs/5.0> Starting mysqld daemon with databases from /home/openxs/d bs/5.0/var openxs@suse:~/dbs/5.0> bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.0.42-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show processlist; +----+------+----------------+-------+---------+------+-------+----------------- -+ | Id | User | Host | db | Command | Time | State | Info | +----+------+----------------+-------+---------+------+-------+----------------- -+ | 1 | root | localhost:1289 | mysql | Sleep | 9 | | NULL | | 2 | root | localhost | test | Query | 0 | NULL | show processlist | +----+------+----------------+-------+---------+------+-------+----------------- -+ 2 rows in set (0.00 sec) mysql> select * from mysql.func; +--------+-----+--------+----------+ | name | ret | dl | type | +--------+-----+--------+----------+ | mytest | 1 | udf.so | function | +--------+-----+--------+----------+ 1 row in set (0.00 sec) mysql> exit Bye openxs@suse:~/dbs/5.0> cat udf4.c #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <unistd.h> #include "mysql.h" /*#include "udf.h"*/ #define ABSPATH "/home/openxs/dbs/5.0/lib/mysql" void CreateThread(void* entryPoint, void *data){ pthread_t* threadId = (pthread_t*) malloc(sizeof(pthread_t)); int rc = 0; pthread_attr_t attr; if (entryPoint == NULL){ return; } rc = pthread_attr_init(&attr); if (rc) { return ; } rc = pthread_create(threadId, &attr, (void*(*)(void*))entryPoint, data); if(rc){ return ; } return; } void ThreadFunc(void *data) { MYSQL * mysqlStruct = NULL; void *handle = dlopen(ABSPATH "/libmysqlclient_r.so", RTLD_NOW | RTLD_DEEPBIND); void *myd_init; void *myd_real_connect; if (!handle) { printf("Failed to open: %s\n", dlerror()); exit(1); } myd_init=dlsym(handle, "mysql_init"); if (!myd_init) { printf("Failed to load symbol: %s\n", dlerror()); exit(1); } myd_real_connect=dlsym(handle, "mysql_real_connect"); if (!myd_real_connect) { printf("Failed to load symbol: %s\n", dlerror()); exit(1); } mysqlStruct = ((MYSQL *(*)(MYSQL *))myd_init)(NULL); sleep(2); mysqlStruct = ((MYSQL *(*)(MYSQL *, const char *, const char *, const char *, const char *, unsigned int, const char *, unsigned long))myd_real_connect)(mysqlStruct, "127.0.0.1", "root", "", "mysql", 3306, NULL, 0); } void __attribute__ ((constructor)) dl_init(void){ CreateThread((void*)ThreadFunc,NULL); } void __attribute__ ((destructor)) dl_deinit(void){} double mytest(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error){retur n 0.;} my_bool mytest_init(UDF_INIT *initid, UDF_ARGS *args, char *message){return 0;} void mytest_deinit(UDF_INIT *initid){} openxs@suse:~/dbs/5.0> getconf GNU_LIBC_VERSION glibc 2.3.4 But, in any case, this default linking to wrong (server's) code instead of one from libmysqlclient*, should be at least explicitely documented. Also, crashing of server when one just tried to add some weird UDF, and never called it (!), is also a problem to solve.
[8 May 2007 19:05]
Antony Curtis
A possible solution/workaround is for the plugin to statically link/include the MySQL client library. My only major concern is how subsequent libraries will be resolved. A better long-term fix would be to ensure that the 'internal' versions of the mysql client operate in a different namespace than the public client. Since this would not change any of the published 'apis' it would not cause any breakages. The mysql daemon is mostly a C++ application and if we could wrap all its global declarations in a namespace to render then casually inaccessible, it would also releive similar problems as was encountered by Falcon in its early days with same-named class declarations.
[11 May 2007 14:24]
Sergei Golubchik
There's no bug here. Functions in the server, even if they have the same name as the client C API functions, are in the server - they can only be called in the server context, and only if certain calling conventions are followed. In particular, they expect a THD context. If you to use these functions from a separate thread, you need to create a THD for it.