Summary: | =dev-db/mariadb-10.1.29 with =sys-auth/libnss-mysql-1.5_p20060915-r3 - checkconfig crashes if mysqld is already running and libnss-mysql is in use | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | Jaco Kroon <jaco> |
Component: | Current packages | Assignee: | Gentoo Linux MySQL bugs team <mysql-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | Normal | ||
Version: | unspecified | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Package list: | Runtime testing required: | --- |
Description
Jaco Kroon
2018-03-08 15:49:37 UTC
Just some additional information I've managed to track down this morning on a debug host: arthur ~ # for file in /usr/sbin/mysqld /usr/lib64/libmysqlclient.so.18 /usr/lib64/libnss_mysql.so.2.0.0; do echo $file:; objdump -T $file | grep '[[:space:]]mysql_real_connect$'; done /usr/sbin/mysqld: 000000000052c780 g DF .text 0000000000000dae Base mysql_real_connect /usr/lib64/libmysqlclient.so.18: 000000000002dd00 g DF .text 0000000000000000 (libmysqlclient_16) mysql_real_connect 000000000002dd00 g DF .text 0000000000000e45 libmysqlclient_18 mysql_real_connect /usr/lib64/libnss_mysql.so.2.0.0: 0000000000000000 DF *UND* 0000000000000000 libmysqlclient_18 mysql_real_connect Based on the above, libnss_mysql will (to my understanding) invoke the version from the shared library (version matches). The library should be initialised. /usr/sbin/mysqld: 000000000052a320 g DF .text 00000000000000bf Base mysql_init /usr/lib64/libmysqlclient.so.18: 000000000002b820 g DF .text 00000000000000cf libmysqlclient_18 mysql_init 000000000002b820 g DF .text 0000000000000000 (libmysqlclient_16) mysql_init /usr/lib64/libnss_mysql.so.2.0.0: 0000000000000000 DF *UND* 0000000000000000 libmysqlclient_18 mysql_init Again, should not be a problem. Assuming that there are no other undesired interaction between the two. #0 The code resulting in the problem (unwinding the stack): void thd_increment_bytes_received(void *thd, ulong length) { ((THD*) thd)->status_var.bytes_received+= length; } Implies that likely thd is null ... GDB confirms. Going down #1, this comes from net->thd, but it's not touched elsewhere in my_real_read that I can see. #2 has #1 as the first call and definitely doesn't touch net->thd. #3 cli_safe_read gets the net argument from mysql->net. #4 mysql_real_connect reveals that net is a struct (not pointer to) inside mysql, and mysql_real_connect uses & to get the NET* for down functions. It also doesn't touch net->thd, only vio (quite a bit). Ok, so the only other thing is then mysql_init(), which is called on the MYSQL* just prior to it being handed to mysql_real_connect. mysql_init sets the entire struct to zero, and then starts filling it out. net->thd is thus never initialized, and I'm not sure where it would normally get initialized from. For *client* this may not be a problem because in sql/net_serv.cc (line 99 on): #ifdef MYSQL_SERVER ... #else #define update_statistics(A) #define thd_net_is_killed() 0 #endif And then on the line in #1: update_statistics(thd_increment_bytes_received(net->thd, length)); Implies that for the client library this never happens. So somehow it ends up that we're calling the mysqld version of my_real_read instead of the client library version. According to objdump this symbol isn't exported from anywhere. my_net_read_packet (#2) is exported from mysqld, but neither libmysqlclient nor libnss_mysql has a reference to that symbol (objdump -T at least). The same for cli_safe_read (#3). The first symbol imported/exported is mysql_real_connect - this implies that libnss_mysql is loading the "Base" version instead of the versioned variant from libmysqlclient. Not sure how to approach that particular issue. A few possible solutions I can think off of hand: 1. Test for thd to be not-null in thd_increment_bytes_received (or the caller even). There seems to be similar checks in thd_increment_bytes_sent (same function). Likely to just have a cascading effect of more such locations. This I can attempt. 2. Fix it so that the libmysqlclient versions of stuff are used and not the mysqld ones. This would likely be the better solution; or possibly: 3. Don't export the symbols from mysqld binary to begin with. Might be the way to achieve (2). If someone can point me in a direction I'll attempt a patch. Would need some pointers for 2/3 as to where to begin with. 1 I should be OK with. Just spotted this again with: * Searching for mariadb ... * Searching for libnss-mysql ... * Searching for mysql-connector-c ... This crash occurred while the server was calling initgroups(). This is often due to the use of a mysqld that is statically linked against glibc and configured to use LDAP in /etc/nsswitch.conf. You will need to either upgrade to a version of glibc that does not have this problem (2.3.4 or later when used with nscd), disable LDAP in your nsswitch.conf, or use a mysqld that is not statically linked. Implies mysqld might be statically linked, and "ldd $(which mysqld)" indeed indicates that mysqld (whilst not static linked) doesn't link against libmysqlclient.so, so I have to assume that it's using it's own internal version for replication which is where libnss-mysql is probably picking up a conflict. (gdb) bt #0 thd_increment_bytes_received (thd=0x0, length=4) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql/sql_class.cc:3994 #1 0x00005555558c9cbe in my_real_read (net=0x7ffff539b228, complen=complen@entry=0x7fffffffce68, header=header@entry=0 '\000') at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql/net_serv.cc:954 #2 0x00005555558caa51 in my_net_read_packet (net=net@entry=0x7ffff539b228, read_from_server=read_from_server@entry=0 '\000') at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql/net_serv.cc:1140 #3 0x0000555555a7a85f in cli_safe_read (mysql=mysql@entry=0x7ffff539b228) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql-common/client.c:581 #4 0x0000555555a7e6cc in mysql_real_connect (mysql=0x7ffff539b228, host=0x555555efa298 "localhost", user=<optimized out>, passwd=0x7ffff539a9a4 "0yEY6fI815KiEWZT", db=<optimized out>, port=3306, unix_socket=0x555556fadf58 "/var/run/mysqld/mysqld.sock", client_flag=0) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql-common/client.c:3467 #5 0x00007ffff519495e in ?? () from /usr/lib64/libnss_mysql.so.2 #6 0x00007ffff5194ce7 in ?? () from /usr/lib64/libnss_mysql.so.2 #7 0x00007ffff5194f5e in ?? () from /usr/lib64/libnss_mysql.so.2 #8 0x00007ffff5195752 in _nss_mysql_initgroups_dyn () from /usr/lib64/libnss_mysql.so.2 #9 0x00007ffff58873b2 in ?? () from /lib64/libc.so.6 #10 0x00007ffff5887697 in initgroups () from /lib64/libc.so.6 #11 0x0000555555ecbf14 in my_set_user (user=<optimized out>, user_info=0x7ffff5b7dec0, MyFlags=MyFlags@entry=16) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/mysys/my_setuser.c:71 #12 0x00005555558c2b88 in set_user (user=<optimized out>, user_info_arg=<optimized out>) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql/mysqld.cc:2371 #13 0x00005555558c8cf7 in mysqld_main (argc=<optimized out>, argv=<optimized out>) at /var/tmp/portage/dev-db/mariadb-10.1.34/work/mysql/sql/mysqld.cc:5726 #14 0x00007ffff57e0011 in __libc_start_main () from /lib64/libc.so.6 #15 0x00005555558bd10a in _start () Confirms that the call is going back into mysqld instead of using libmysqlclient. I suspect mariadb should not export the client symbols such that the libnss-mysql component will utilize the symbols from the library instead. I don't know how to do that. This no longer seems to be a problem, so I'm going to close this as FIXED. |