3

私はMySQL 5.0.51aを使用していますが、プログラムの終了時に無限ループ (スタック オーバーフローと seqgfault で終了) を引き起こしているバグを発見しました。

という関数がある場合shutdown()、 の呼び出し中に によって呼び出されることを発見しましたmysql_close()

実際の問題を示すために、最小限の C ソース ファイルと makefile の例を以下に示します。この例では、shutdown()によって呼び出されていないにもかかわらず、 が呼び出されmain()ます。

ここで何が起こっているのですか?libmysqlclientshutdown()と衝突していshutdown()ますか? もしそうなら、gccがそれを知らない理由はありますか?

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

メイクファイル:

mysql_shutdown: mysql_shutdown.c
        gcc  -Wall -Wextra -Werror `mysql_config --cflags` -o $@ $^ `mysql_config --libs`

出力:

$ ./mysql_shutdown
shutdown called

これは、 GCC function name conflictに示されているものとは反対の動作であるように見えることに注意してください。その場合、期待される関数は呼び出されていませんでしたが、私の場合、期待されていないときに関数が呼び出されています。

4

1 に答える 1

1

最も可能性が高いのmysql_config --libsは、MySQL ライブラリ ファイルのリストが表示され、shutdown()関数がライブラリ内ののオブジェクト ファイルにあるため、取り込まれていないことです。

ほとんどのリンカーがどのように機能するかを理解する必要があります。それらが行うことは、明示的にリストしたすべてのオブジェクト ファイルを結合することであり、部分的な実行可能ファイルと、まだ解決されていないシンボルのリストになります。

次に、シンボルを解決できるライブラリ内のオブジェクト ファイルを見つけることによって、それらのシンボルを解決するためにライブラリが検索されます。通常、ライブラリの 1 つを見つけmysql_close()て、そのライブラリからオブジェクト ファイルをロードします。しかし、そのアクションにより、解決が必要なシンボルがさらに導入される可能性があり、その結果、より多くのライブラリが検索される可能性があります。

例として、MySQL ライブラリの 1 つで通常提供されるmysql_close()呼び出しについて考えてみましょう。shutdown()ただし、既に定義されているため、 をロードしても未解決のシンボルが発生することはありmysql_close()ません。shutdownそのため、どのライブラリでも探しに行く必要はありません。

コードで提供したものとmysql_close()まったく異なる を呼び出すことにshutdown()なります。

于 2013-08-13T08:41:25.757 に答える