Reputation: 1702
I'm using MySQL 5.0.51a and I uncovered a bug which was causing an infinite loop (ending in a stack overflow and seqgfault) when my program was exiting.
I discovered that if I had a function called shutdown()
, it would be called by during a call to mysql_close()
.
I've included a mimimal example C source file and makefile below to show the issue in action.
In the example, shutdown()
gets called despite not being called by main()
.
What is going on here? Is my shutdown()
clashing with a shutdown()
in libmysqlclient?
If so, is there a reason gcc doesn't know about it?
I'm using gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
mysql_shutdown.c:
#include <stdio.h>
#include <mysql/mysql.h>
#define HOST "<hostname>"
#define USER "<username>"
#define PASSWD "<password>"
#define DB "<dbname>"
MYSQL *connection;
void shutdown(void)
{
printf("shutdown called\n");
}
int main()
{
connection = mysql_init(NULL);
mysql_real_connect(connection, HOST, USER, PASSWD, DB, 0, NULL, 0);
mysql_close(connection);
return 0;
}
makefile:
mysql_shutdown: mysql_shutdown.c
gcc -Wall -Wextra -Werror `mysql_config --cflags` -o $@ $^ `mysql_config --libs`
Output:
$ ./mysql_shutdown
shutdown called
Note that this appears to be the opposite behaviour to that shown in GCC function name conflict. In that case the expected function wasn't being called, whereas in my case, a function is being called when it isn't expected.
Upvotes: 3
Views: 428
Reputation: 881403
What's most likely happening is that, because mysql_config --libs
is giving you a list of the MySQL library files and the shutdown()
function is in a different object file within the library(s), it's not being bought in.
You have to understand the way most linkers work. What they will do is tie together all the object files that you list explicitly and you end up with a partial executable and a list of symbols that have yet to be resolved.
Then the libraries are searched in an effort to resolve those symbols, by locating the object files within those libraries which can resolve the symbols. Normally what may happen is that you'll find mysql_close()
in one of the libraries and load up its object file from that library. But that action may introduce more symbols that need resolving, which can in turn lead to more libraries being searched.
As an example, let's say mysql_close()
calls shutdown()
which is normally provided in one of the MySQL libraries. However, because you've already defined it, the loading of mysql_close()
does not result in having an unresolved shutdown
symbol. So there's no need to go looking for it in any of the libraries.
It does result in mysql_close()
calling a totally different shutdown()
, the one you provided in your code.
Upvotes: 1