Bug #66484 Static linked C API clients fail to initialise character set
Submitted: 21 Aug 2012 15:41 Modified: 21 Feb 2013 17:33
Reporter: Pete French Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S2 (Serious)
Version:5.5.27 OS:FreeBSD
Assigned to: CPU Architecture:Any

[21 Aug 2012 15:41] Pete French
Description:
Code of the following form...

        mysql_init(&the_db);
        mysql_options(&the_db, MYSQL_SET_CHARSET_NAME, "utf8");
        mysql_options(&the_db, MYSQL_OPT_RECONNECT, &mysql_true);
        if(!mysql_real_connect(&the_db, "localhost",...

works fine under 5.1, and also works under 5.5 if linked against the dynamic libraries. uIf I link it statically, however, then uder 5.5 it fails with this error:

Character set 'utf-8' is not a compiled character set and is not specified in the '/usr/local/share/mysql/charsets/Index.xml' file
Can't initialize character set utf-8 (path: /usr/local/share/mysql/charsets/)

How to repeat:
A very simple piece of C code which makes an API connection as above will demonstrate the error. I am using FreeBSD 8.3, but I d not think this is related to the OS version.
[23 Aug 2012 19:00] Sveta Smirnova
Thank you for the report.

I can not repeat described behavior with current development sources. Additionally version 5.5.25 is a bit outdated. Please try with current version 5.5.27 and if problem still exists provide command line you use to compile with static libraries.
[24 Aug 2012 16:12] Pete French
I just tried. The same problem exists on 5.5.27. I am using the following two command lines to compile my test program:

(working)
cc -Wall -I/usr/local/include -L/usr/local/lib/mysql mysql_client_test.c -lmysqlclient -lm -lz

(not working)
cc -static -Wall -I/usr/local/include -L/usr/local/lib/mysql mysql_client_test.c -lmysqlclient -lm -lz

The code for mysql_client_test is below. I am compiling mysql with
the followng make options:

WITH_CHARSET=utf8
WITH_COLLATION=utf8_general_ci
BUILD_OPTIMIZED=yes
WITH_OPENSSL=yes
WITHOUT_YASSL=yes

here is the code for my test program:

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>

#include <mysql/mysql.h>

#define THE_USER        "testuser"

int
main(int argc, char *argv[])
{
        MYSQL the_db;
        my_bool mysql_true = 1;

        mysql_init(&the_db);
        mysql_options(&the_db, MYSQL_SET_CHARSET_NAME, "utf8");
        mysql_options(&the_db, MYSQL_OPT_RECONNECT, &mysql_true);
        if(!mysql_real_connect(&the_db, "localhost", THE_USER, THE_USER,
                        NULL, 0, NULL, 0)) {
                printf("%s\n", mysql_error(&the_db));
                return 1;
        }

        puts("Connected fine");
        mysql_close(&the_db);
        return 0;
}
[3 Sep 2012 18:49] Sveta Smirnova
Thank you for the feedback.

Which compiler do you use?
[4 Sep 2012 12:27] Pete French
I use the system compiler - under FreeBSD 8.3 this is gcc 4.2.1.

This shpuld be very easy to reproduce on a vanilla FreeBSD 8.3 system (I am using the 64 bit version, have not tested 32 bit). Simply installing the mysqy port, setting up a user and compiling the above program will show it. Are you having problems reproducing the bug ?
[4 Sep 2012 16:33] Sveta Smirnova
Thank you for the feedback.

Verified as described on FreeBSD 8.2
[21 Feb 2013 17:33] Igor Solodovnikov
Libmysql uses pthread_once() function to initialize internal charsets array in multithreaded environment.
The problem caused by user's command line for compiler which does not include -pthread option. Without this option linker uses pthread_once() implementation from libc.
Unfortunately on FreeBSD libc contains only stub version of pthread_once() which does not call passed pointer to charset initialization toutine. So internal charsets array is never initialized.

Actually user can execute mysql_config tool with --libs option to get
recommended command line options. On FreeBSD 8.3 it will look as this:

$ mysql_config --libs
-L/usr/local/lib/mysql -lmysqlclient  -pthread -lz -lm

-pthread option is missing from original command line. Adding it to
compiler's command line will fix the problem:

cc -static -Wall -I/usr/local/include -L/usr/local/lib/mysql mysql_client_test.c -lmysqlclient -pthread -lthr -lm -lz

Bug closed as 'not a bug'.