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:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1.13/Bk source OS:Linux (Linux)
Assigned to: Andrey Hristov CPU Architecture:Any

[23 Aug 2005 3:50] Oliver Smith
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
[25 Aug 2005 0:57] Miguel Solorzano
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] Miguel Solorzano
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