Ich erstelle eine C-Anwendung auf der Linux-Plattform. Ich muss libmysqlclient verwenden, um mit der Datenbank zu interagieren.
Ich habe das Linux-Quellcodepaket mysql-connector-c-6.0.2.tar.gz heruntergeladen. Ich habe es gemäß den Anweisungen kompiliert. Ich erhalte die folgenden Bibliotheken:
libmysqlclient.a libmysqlclient.so libmysql.so.16
libmysqlclient_r.so libmysql.so libmysql.so.16.0.0
Wenn meine Anwendung mehrere Threads hat, kann ich meine Anwendung mit libmysqlclient.a verknüpfen? Laut der MySQL-Dokumentation (http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide) sind Clients mit dem CMake-Tool immer thread-sicher.
Nachdem ich meine Anwendung mit libmysqlclient.a verknüpft habe, stürzt meine Anwendung mit untenstehendem Aufrufstapel ab:
#0 0x0867878a in my_stat ()
Keine Symboltabelleninformationen verfügbar.
#1 0x08671611 in init_available_charsets.clone.0 ()
Keine Symboltabelleninformationen verfügbar.
#2 0x086720d5 in get_charset_by_csname ()
Keine Symboltabelleninformationen verfügbar.
#3 0x086522af in mysql_init_character_set ()
Keine Symboltabelleninformationen verfügbar.
#4 0x0865266d in mysql_real_connect ()
In meiner Anwendung habe ich folgenden Code in der Thread-Funktion:
if (NULL == (pMySQL = mysql_init(NULL)))
{
return -1;
}
if (NULL == mysql_real_connect(pMySQL, ServerName, UserName, Password, Name, Port, NULL, 0))
{
mysql_close(pMySQL);
return -1;
}
if (0 != mysql_query(pMySQL, pQuery))
{
mysql_close(pMySQL);
return -1;
}
mysql_close(pMySQL);
Ich verwende libmysqlclient_r.so nicht, da ich die Verknüpfung mit der MySQL-Clientbibliothek statisch durchführen möchte. Gibt es eine Möglichkeit, libmysqlclient_r.a mit CMake zu generieren?
Aktualisierung:
Ohne etwas anderes zu tun, habe ich einfach den Build-Typ des MySQL-Clients auf Debug geändert. Jetzt stürze ich in der Funktion mysql_init() ab.
Auf der Konsolenanwendung erhalte ich folgende Ausgabe:
safe_mutex: Versuch, uninitialisiertes Mutex bei /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c, Zeile 520 zu sperren
Der Aufrufstapel des Absturzes sieht wie folgt aus:
#0 0x00556430 in __kernel_vsyscall ()
Keine Symboltabelleninformation verfügbar.
#1 0x45fdf2f1 in raise () von /lib/libc.so.6
Keine Symboltabelleninformation verfügbar.
#2 0x45fe0d5e in abort () von /lib/libc.so.6
Keine Symboltabelleninformation verfügbar.
#3 0x086833e5 in safe_mutex_lock (mp=0x915e8e0, my_flags=0,
file=0x895b9d8 "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c", line=520)
at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/thr_mutex.c:178
error = 140915306
__PRETTY_FUNCTION__ = "safe_mutex_lock"
#4 0x08682715 in _sanity (
filename=0x895a87c "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c", lineno=195)
at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c:520
irem = 0xf2300468
flag = 0
count = 0
#5 0x0868186b in _mymalloc (size=16,
filename=0x895a87c "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c", lineno=195, MyFlags=16)
at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c:130
irem = 0x0
data = 0x0
_db_stack_frame_ = {func = 0x6d617266
Lösung:
Ich habe einen Aufruf von mysql_library_init() vor der Erstellung der Threads platziert und einen Aufruf von mysql_library_end() nach der Beendigung der Threads platziert. In jedem Thread habe ich einen Aufruf von mysql_thread_init() am Anfang der Thread-Funktion platziert und einen Aufruf von mysql_thread_end() am Ende der Thread-Funktion platziert. Das hat das Problem des Absturzes gelöst.