Bug #2062 libmysql can kill the entire application by calling exit(1)
Submitted: 9 Dec 2003 11:42 Modified: 10 Dec 2003 6:25
Reporter: [ name withheld ] Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:4.0.16 OS:Mac OS X (Mac OS X)
Assigned to: Michael Widenius

[9 Dec 2003 11:42] [ name withheld ]
Description:
In my_thread_global_init() in my_thr_init.c, the library attempts to create a pthread key by calling pthread_key_create().
If it fails, it prints an error to stderr and calls exit(1).
This quits the entire application!

So if the application calls mysql_init(NULL), and this ends up calling pthread_key_create, which for some reason fails, then the application immediately quits - it does not get a chance to put up an error message, or abort cleanly, or anything.

How to repeat:
Make an application that creates 128 pthread keys, then does something with mysql.
(if PTHREAD_KEYS_MAX is different for you, you might have to use a different number of keys)

int 
main(int argc, char *argv[])
{
	int i;
	MYSQL *db;
	pthread_key_t key;

	for (i=0; i< 128; i++) {
		if(pthread_key_create(&key, NULL))
			printf("failed to make key %d.. errno: %d\n", i, errno);
		else
			printf("key %d\n", i);
	}
	printf("created all my keys!\n");
	db = mysql_init(NULL);
	mysql_real_connect(db, "addr", "name", "pass",
				"db", 0, NULL, 0);
	mysql_close(db); 
	printf("expected exit point hit\n");

	return(0);
}

Suggested fix:
Instead of exiting, my_thread_global_init should return true (which seems to be the failure case, judging from my_thread_init()).
This in turn needs to be watched for in my_init, which should then return failure, etc up the call chain.

So if mysql_init(NULL) triggers the pthread_key_create() call which fails, then mysql_init(NULL) should fail.
[10 Dec 2003 6:25] Michael Widenius
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:

I have now changed so that mysql_server_init() returns 1 if it can't initialize the MySQL environment.

This fix will be in 4.0.17 and 4.1.2