| Bug #12744 | MYSQL_STMT operations cause seg fault after connection reset | ||
|---|---|---|---|
| Submitted: | 23 Aug 2005 3:50 | Modified: | 2 Feb 2006 13:04 |
| Reporter: | Oliver Smith | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server | Severity: | S2 (Serious) |
| Version: | 4.1.13/Bk source | OS: | Linux (Linux) |
| Assigned to: | Andrey Hristov | CPU Architecture: | Any |
[25 Aug 2005 0:57]
MySQL Verification Team
I was unable to get a crash handling the error message returned
by mysql_stmt_reset and the prepared statements can't be
recreated.
if (mysql_stmt_reset(stmt))
{
cout << "mysql_stmt_reset error: " << mysql_stmt_error(stmt) << endl;
cout << "Bye" << endl;
return 1;
}
Below the output of the client application:
miguel@hegel:~/dbs/5.0> ./bug12744
Connected to the server: 5.0.13-beta-debug
prepare, INSERT successful
total parameters in INSERT: 3
total affected rows insert 1:1
Shutdown the Server and re-start it! Hit return
mysql_stmt_execute, 2 failed MySQL server has gone away
Calling mysql_stmt_reset(stmt) and expect a nice error
mysql_stmt_reset error: MySQL server has gone away
Bye
[25 Aug 2005 16:26]
Oliver Smith
It's not mysql_stmt_error that is producing the segfault, my call to mysql_stmt_error was to "Prove that stmt has some validity" (see original code).
The segfault arises doing this:
mysql_stmt_execute(stmt);
system("service mysql restart; sleep 10");
mysql_stmt_execute(stmt); //<< returns CR_SERVER_GONE
mysql_stmt_execute(stmt); //<< segfault in 4.0.13
If this is expected behavior, it needs to be very clearly documented because:
a/ It differs from standard MySQL connection loss behavior,
b/ It produces a segfault not an error code
Compare with the following:
mysql_query("create table oliver_kfs_foo (foo int)");
if (mysql_query("truncate oliver_kfs_foo")) cout <<"#1fail ** unexpected"<<endl;
system("service mysql restart;sleep 5");
if (mysql_query("truncate oliver_kfs_foo")) cout <<"#2fail expected"<<endl;
if (mysql_query("truncate oliver_kfs_foo")) cout <<"#3fail ** unexpected"<<endl;
MySQL gracefully recovers.
Many MySQL users are going to assume that server-side statements will keep enough of the construction information to be as robust as a client-side statement and recover gracefully when a server connection gets reset as in the above example.
If the non-graceful recovery is intended functionality, then the bug is that it produces a segfault instead of CR_SERVER_GONE_AWAY; if the code is actually trying to gracefully recover then the bug is that it fails and generates a segfault.
- Oliver
[25 Aug 2005 16:55]
MySQL Verification Team
Yeah sorry I was tested against 5.0.XX and with 4.1.15 I got the crash with the same application: Connected to the server: 4.1.15-debug-log prepare, INSERT successful total parameters in INSERT: 3 total affected rows insert 1:1 Shutdown the Server and re-start it! Hit return mysql_stmt_execute, 2 failed Unknown prepared statement handler (1) given to mysql_stmt_execute Calling mysql_stmt_reset(stmt) and expect a nice error Segmentation fault
[27 Aug 2005 8:52]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/28927
[29 Aug 2005 9:46]
Andrey Hristov
Moving to "In Progress" to investigate other places where problems may occur. * ahristov@mysql.com <ahristov@mysql.com> [05/08/27 13:06]: > ChangeSet > 1.2397 05/08/27 10:51:31 andrey@lmy004. +2 -0 > fix for bug #12744 (MYSQL_STMT operations cause seg fault after connection reset) Hello Andrey, the idea of the fix is correct, but please write the following test: - create a statement; - set stmt->mysql= 0; in the test; - try every mysql_stmt_ method and make sure none of them causes a crash. Potentially a connection may be reset at any point after a statement was created (e.g. simply trying mysql_ping(mysql) may discover that the server has gone away, and this will trigger reset of all prepared statement associated with this connection on the client side). Thank you for looking into this.
[1 Feb 2006 19:37]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/2023
[1 Feb 2006 19:39]
Andrey Hristov
Fixed in 4.1.19
[2 Feb 2006 13:04]
Jon Stephens
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.
If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information
about accessing the source trees is available at
http://www.mysql.com/doc/en/Installing_source_tree.html
Additional info:
Documented in 4.1.19 changelog; closed.
[6 Feb 2006 14:59]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/2194

Description: If a MySQL server resets, MySQL STMTs are not recovered, instead they enter an undefined state which invariably leads to a segfault if re-used. How to repeat: 8x--- snip ---x8 { stmt = initPrepAndBind(); if ( mysql_stmt_execute(stmt) ) throw runtime_error("#1 failed"); // HUP the database server and wait for it to recover system("ssh database service restart mysql"); sleep(10); if (mysql_stmt_execute(stmt)) { // Prove that stmt has some validity cout << "the error was " << mysql_stmt_error(stmt) << endl; // But usage produces fatal behavior mysql_stmt_reset(stmt); // -- segfault } cout << "we reached the end of the code" << endl; } 8x-- snip ---x8