Bug #2062 libmysql can kill the entire application by calling exit(1)
Submitted: 9 Dec 2003 12:42 Modified: 10 Dec 2003 7:25
Reporter: [ name withheld ]
Status: Closed
Category:Server Severity:S1 (Critical)
Version:4.0.16 OS:Mac OS X (Mac OS X)
Assigned to: Bugs System Target Version:

[9 Dec 2003 12: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 7: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