2

Linux プラットフォームで C アプリケーションを構築しています。データベースとのインターフェースには libmysqlclient を使用する必要があります。

Linux ソース コード パッケージ mysql-connector-c-6.0.2.tar.gz をダウンロードしました。説明書通りにまとめました。以下のライブラリを取得します。

libmysqlclient.a     libmysqlclient.so  libmysql.so.16
libmysqlclient_r.so  libmysql.so        libmysql.so.16.0.0

アプリケーションがマルチスレッドの場合、アプリケーションを libmysqlclient.a とリンクできますか? mysql のドキュメント ( http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide ) によると、cmake ツールを使用すると、クライアントは常にスレッド セーフになります。

アプリケーションを libmysqlclient.a にリンクした後、以下のコール スタックでアプリケーションがクラッシュします。

#0  0x0867878a in my_stat ()
No symbol table info available.
#1  0x08671611 in init_available_charsets.clone.0 ()
No symbol table info available.
#2  0x086720d5 in get_charset_by_csname ()
No symbol table info available.
#3  0x086522af in mysql_init_character_set ()
No symbol table info available.
#4  0x0865266d in mysql_real_connect ()

私のアプリケーションでは、スレッド関数に以下のコードがあります。

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);

mysql クライアント ライブラリに静的にリンクしたいので、libmysqlclient_r.so を使用していません。cmake で libmysqlclient_r.a を生成する方法はありますか?

アップデート:

他に何もせずに、mysql クライアントのビルド タイプをデバッグに変更しました。これで、mysql_init() 関数でクラッシュが発生しました。

アプリケーション コンソールでは、以下のように表示されます。

safe_mutex: Trying to lock unitialized mutex at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c, line 520

クラッシュのコール スタックは次のとおりです。

#0  0x00556430 in __kernel_vsyscall ()
No symbol table info available.
#1  0x45fdf2f1 in raise () from /lib/libc.so.6
No symbol table info available.
#2  0x45fe0d5e in abort () from /lib/libc.so.6
No symbol table info available.
#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 <Address 0x6d617266 out of bounds>, file = 0x65685f65 <Address 0x65685f65 out of bounds>,
          level = 0, prev = 0x0}
#6  0x0867e0e1 in my_error_register (errmsgs=0x89a7760, first=2000, last=2058)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c:194
        meh_p = 0x46087568
        search_meh_pp = 0x1000
#7  0x08655f7e in init_client_errs ()
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/errmsg.c:238
No locals.
#8  0x08655fe3 in mysql_server_init (argc=0, argv=0x0, groups=0x0)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/libmysql.c:128
        result = 0
#9  0x08651fc0 in mysql_init (mysql=0x0)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/client.c:1606

解決:

スレッドの作成前に mysql_library_init() を呼び出し、スレッドの終了後に mysql_library_end() を呼び出しました。各スレッドで、スレッド関数の開始時に mysql_thread_init() への呼び出しを配置し​​、スレッド関数の最後に mysql_thread_end() への呼び出しを配置し​​ました。これでクラッシュの問題は解決しました。

4

1 に答える 1

3

更新

前にmysql_library_init()を呼び出す必要があるようですmysql_init():

スレッドを生成する前に mysql_library_init() を呼び出すか、または mysql_library_init() を呼び出すか mysql_init() を介して間接的に呼び出すかにかかわらず、mutex を使用して呼び出しを保護する必要があります。これは、他のクライアント ライブラリ呼び出しの前に行ってください。

元の質問に関してlibmysqlclient_r.soは、実際にはへのシンボリックリンクlibmysql.soです。次の行からキーワードを削除することで、代わりにlibmysql/CMakeLists.txtスタティック ライブラリ ( ) を生成するように変更できます。libmysql.aSHARED

ADD_LIBRARY(libmysql          SHARED ${CLIENT_SOURCES} libmysql.def)

ただし、(1) スレッドを使用せずに同じコードを実行して、問題が解決しないかどうかを確認すること、(2) ライブラリのデバッグ バージョンをビルドして使用することをお勧めします。

cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
make

このようにして、問題をより詳細に調査できます。

于 2012-07-03T15:45:22.373 に答える