Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.1Mb
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


24.4.1.5 スタックトレースの使用

オペレーティングシステムによっては、mysqld が予期せずに異常終了した場合に、エラーログにスタックトレースが含まれています。これを使用して、mysqld が異常終了した場所 (および多くの場合その理由) を見つけることができます。セクション5.2.2「エラーログ」 を参照してください。スタックトレースを取得するには、-fomit-frame-pointer オプションを gcc に指定して mysqld をコンパイルしないでください。セクション24.4.1.1「デバッグのための MySQL のコンパイル」を参照してください。

エラーログのスタックトレースは次のように出力されます。

mysqld got signal 11;
Attempting backtrace. You can use the following information
to find out where mysqld died. If you see no messages after
this, something went terribly wrong...

stack_bottom = 0x41fd0110 thread_stack 0x40000
mysqld(my_print_stacktrace+0x32)[0x9da402]
mysqld(handle_segfault+0x28a)[0x6648e9]
/lib/libpthread.so.0[0x7f1a5af000f0]
/lib/libc.so.6(strcmp+0x2)[0x7f1a5a10f0f2]
mysqld(_Z21check_change_passwordP3THDPKcS2_Pcj+0x7c)[0x7412cb]
mysqld(_ZN16set_var_password5checkEP3THD+0xd0)[0x688354]
mysqld(_Z17sql_set_variablesP3THDP4ListI12set_var_baseE+0x68)[0x688494]
mysqld(_Z21mysql_execute_commandP3THD+0x41a0)[0x67a170]
mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x282)[0x67f0ad]
mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xbb7[0x67fdf8]
mysqld(_Z10do_commandP3THD+0x24d)[0x6811b6]
mysqld(handle_one_connection+0x11c)[0x66e05e]

トレースの関数名の解決に失敗した場合、トレースに格納される情報が少なくなります。

mysqld got signal 11;
Attempting backtrace. You can use the following information
to find out where mysqld died. If you see no messages after
this, something went terribly wrong...

stack_bottom = 0x41fd0110 thread_stack 0x40000
[0x9da402]
[0x6648e9]
[0x7f1a5af000f0]
[0x7f1a5a10f0f2]
[0x7412cb]
[0x688354]
[0x688494]
[0x67a170]
[0x67f0ad]
[0x67fdf8]
[0x6811b6]
[0x66e05e]

後者の場合は、resolve_stack_dump ユーティリティーを使用して、次の手順を使用することによって、mysqld が異常終了した場所を判別できます。

  1. スタックトレースから mysqld.stack などのファイルに数値をコピーします。この数値には、囲んでいた角括弧を含めないでください。

    0x9da402
    0x6648e9
    0x7f1a5af000f0
    0x7f1a5a10f0f2
    0x7412cb
    0x688354
    0x688494
    0x67a170
    0x67f0ad
    0x67fdf8
    0x6811b6
    0x66e05e
    
  2. mysqld サーバーのシンボルファイルを作成します。

    shell> nm -n libexec/mysqld > /tmp/mysqld.sym
    

    mysqld が静的にリンクされていない場合は、代わりに次のコマンドを使用します。

    shell> nm -D -n libexec/mysqld > /tmp/mysqld.sym
    

    C++ のシンボルをデコードする場合は、nm に対して --demangle を使用します (使用できる場合)。使用しているバージョンの nm にこのオプションがない場合は、スタックダンプが生成されたあとに c++filt コマンドを使用して、C++ 名をデマングルする必要があります。

  3. 次のコマンドを実行します。

    shell> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack
    

    デマングルされた C++ 名をシンボルファイルに含めることができなかった場合は、c++filt を使用して resolve_stack_dump の出力を処理します。

    shell> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack | c++filt
    

    これにより、mysqld が異常終了した場所が出力されます。この出力が、mysqld が異常終了した理由を見つけるために役立たない場合は、バグレポートを作成して、上記のコマンドの出力をバグレポートに含めてください。

    ただし、多くの場合、スタックトレースだけがあっても問題の原因を見つけるために役立ちません。バグを見つけたり回避策を提供したりするためには、ほとんどの場合、mysqld が強制終了されたステートメントを知る必要があり、問題を再現できるテストケースがあれば役に立ちます。セクション1.7「質問またはバグをレポートする方法」を参照してください。

新しいバージョンの glibc スタックトレース関数では、オブジェクトへの相対アドレスも出力されます。glibc ベースのシステム (Linux) では、プラグイン内でのクラッシュのトレースは次のようになります。

plugin/auth/auth_test_plugin.so(+0x9a6)[0x7ff4d11c29a6]

相対アドレス (+0x9a6) をファイル名および行番号に変換するには、次のコマンドを使用します。

shell> addr2line -fie auth_test_plugin.so 0x9a6
auth_test_plugin
mysql-trunk/plugin/auth/test_plugin.c:65

addr2line ユーティリティーは Linux の binutils パッケージの一部です。

Solaris でも手順は同様です。Solaris の printstack() では、相対アドレスがすでに出力されています。

plugin/auth/auth_test_plugin.so:0x1510

これを変換するには、次のコマンドを使用します。

shell> gaddr2line -fie auth_test_plugin.so 0x1510
mysql-trunk/plugin/auth/test_plugin.c:88

Windows では、アドレス、関数名、および行がすでに出力されています。

000007FEF07E10A4 auth_test_plugin.dll!auth_test_plugin()[test_plugin.c:72]

User Comments
  Posted by Martin Mokrejs on January 12, 2004
This is a nice way to resolve the stack trace:

echo "This scripts expects stack trace from your mysql error log file"
echo "placed in the current directory as ./stack"

if [ ! -r ./stack ]; then
echo "./stack file not present or readable"
exit 255
fi

if [ -r /usr/local/mysql/bin/mysqld.sym.gz ]; then
gzip -dc /usr/local/mysql/bin/mysqld.sym.gz > ./symbols
else
echo "nm -n /usr/local/mysql/bin/mysqld > ./symbols"
nm -n /usr/local/mysql/bin/mysqld > ./symbols
fi

echo "/usr/local/mysql/bin/resolve_stack_dump -s ./symbols -n ./stack"
/usr/local/mysql/bin/resolve_stack_dump -s ./symbols -n ./stack

# if you have c++ filter, use rather this output, it's even better
echo "if you don't have c++filter, the next command will fail"
echo "/usr/local/mysql/bin/resolve_stack_dump -s ./symbols -n ./stack | c++filter"
/usr/local/mysql/bin/resolve_stack_dump -s ./symbols -n ./stack | c++filter

  Posted by Martin Mokrejs on January 12, 2004
In my previous comment in the shellscript should be c++filt instead of c++filter. c++filt is a part of gcc package.
Sign Up Login You must be logged in to post a comment.