Bug #55932 | handle_sigint -> mysql_get_server_version crashes if no connection | ||
---|---|---|---|
Submitted: | 12 Aug 2010 1:22 | Modified: | 11 Jul 2014 4:14 |
Reporter: | [ name withheld ] | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: Command-line Clients | Severity: | S3 (Non-critical) |
Version: | 5.1.48, 5.1-bzr | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[12 Aug 2010 1:22]
[ name withheld ]
[15 Aug 2010 9:52]
Sveta Smirnova
Thank you for the report. Please check if it is duplicate of bug #50008 or bug #47655: does client connects to older server?
[15 Aug 2010 15:32]
[ name withheld ]
Based on the stack trace (see attachment in Red Hat bugzilla) I don't believe this is a duplicate of either of those bugs. However, it could be that there is a server version mismatch contributing to the problem --- the original reporter didn't say whether he was connecting to a local or remote server. I've asked him to clarify that.
[15 Aug 2010 15:39]
Sveta Smirnova
Thank you for the feedback. Please ask: I was not able to repeat using gdb and having breakpoints in locations which stack trace is showing.
[15 Aug 2010 17:13]
Damien Grassart
Yes, I was connecting to an older MySQL server: 4.1.25-pro-gpl-log but I am not sure if those other bugs are related. I can't reproduce this crash either and that was the first and only time it's happened to me, so it seems pretty rare. Let me know if there's any other info I can provide. Thanks, -Damien
[17 Aug 2010 20:02]
Sveta Smirnova
Thank you for the feedback. I still can not repeat described behavior. One thing confuses me. In the trace provided I see my_connect call, then mysql_get_server_version. But there is no mysql_get_server_version in my_connect call. Which binaries do you use?
[18 Aug 2010 14:46]
[ name withheld ]
What the trace looks like to me is that my_connect was interrupted by SIGINT (control-C). It's the signal handler handle_sigint that's calling mysql_get_server_version.
[18 Aug 2010 19:03]
Sveta Smirnova
Thank you for the feedback. But it is not referenced in handle_sigint either. Regular MySQL command line client gets version # from TCP/IP headers and don't ask for server version when reconnects. So is still interesting which client/binaries Damien uses. Part from doxygen output: ulong STDCALL mysql_get_server_version ( MYSQL * mysql ) Definition at line 3229 of file client.c. References mysql, pos(), st_mysql::server_version, strtoul(), and version().
[18 Aug 2010 22:29]
[ name withheld ]
Um ... please note this bug report is against 5.1 branch. I have not looked at the newer branches, but in 5.1.49 there is such a call, line 1309 of client/mysql.cc. [ looks at the code some more ... ] I wonder whether the problem isn't just that that call is referencing &mysql, rather than the new connection kill_mysql that was just set up above that?
[19 Aug 2010 18:53]
Sveta Smirnova
Thank you for the feedback. Verified as described. To repeat modify sources as follow: $bzr diff === modified file 'sql-common/client.c' --- sql-common/client.c 2010-05-10 03:02:05 +0000 +++ sql-common/client.c 2010-08-19 18:33:59 +0000 @@ -3230,7 +3230,10 @@ { uint major, minor, version; char *pos= mysql->server_version, *end_pos; - major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1; + pos=0; + fprintf(stdout, "Disconnect now\n"); + major= (uint) strtoul(pos, &end_pos, sleep(10) + 10); pos=end_pos+1; + fprintf(stdout, "stop disconnecting\n"); minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1; version= (uint) strtoul(pos, &end_pos, 10); return (ulong) major*10000L+(ulong) (minor*100+version); Then connect to 4.1 server, create large table named t1 there, then run query `create temporary table tt1(f1 int) select * from t1;` In other window connect to 4.1 server and run query SHOW PROCESSLIST In window one press Ctrl-C, then after "Disconnect here" in second window kill process running CREATE TEMPORARY TABLE Wait when client crashes.
[19 Aug 2010 18:59]
Sveta Smirnova
Sorry: please ignore previous comment. It was wrong test.
[21 Aug 2010 9:40]
Sveta Smirnova
Correct test to repeat the problem. Diff: $bzr diff === modified file 'client/mysql.cc' --- client/mysql.cc 2010-07-20 18:07:36 +0000 +++ client/mysql.cc 2010-08-21 09:32:41 +0000 @@ -1285,6 +1285,8 @@ { char kill_buffer[40]; MYSQL *kill_mysql= NULL; + + tee_fprintf(stdout, " Ctrl-C -- exit!\n"); /* terminate if no query being executed, or we already tried interrupting */ /* terminate if no query being executed, or we already tried interrupting */ @@ -2760,6 +2762,7 @@ int error; if (!mysql_real_query(&mysql,buf,length)) return 0; + error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || !opt_reconnect) @@ -3988,7 +3991,13 @@ } else opt_rehash= 0; + fprintf(stdout, "Disconnect now\n"); + sleep(10); + fprintf(stdout, "stop disconnecting\n"); error=sql_connect(current_host,current_db,current_user,opt_password,0); + fprintf(stdout, "Connect now\n"); + sleep(10); + fprintf(stdout, "connecting\n"); opt_rehash= save_rehash; if (connected) Then start MySQL Proxy connected to 4.1 backend: mysql-proxy --proxy-backend-addresses=127.0.0.1:3341 Connect to Proxy port using modified 5.1 client: ./client/mysql -h127.0.0.1 -P4040 test Run set global interactive_timeout=1;, set global wait_timeout=1;, reconnect. Run query SHOW TABLES, you get: ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Disconnect now Then go to another terminal and kill MySQL Proxy Then back to client terminal and see: stop disconnecting ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61) Connect now Then restart MySQL Proxy with same parameters. Then back to the client and hit Ctrl^C, you get error: mysql> show tables; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Disconnect now stop disconnecting ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (61) Connect now ^C Ctrl-C -- exit! Bus error
[21 Aug 2010 9:44]
Sveta Smirnova
Problem with test case not repeatable every time. You need to be *not* very fast to repeat it. Suggested fix: in handle_sigint check existence of mysql instance before calling mysql_get_server_version.
[11 Jul 2014 4:14]
Erlend Dahl
This is no longer repeatable on latest versions of 5.5 and 5.6.