Spec-Zone.ru › MySQL 5.7

5.8.1.5 Использование трассировки стека

На некоторых операционных системах журнал ошибок содержит трассировку стека, если mysqld завершается неожиданно. Это можно использовать, чтобы определить, где (и, возможно, почему) mysqld завершился. См. Раздел 5.4.2, «Журнал ошибок». Чтобы получить трассировку стека, необходимо не компилировать mysqld с опцией -fomit-frame-pointer в gcc. См. Раздел 5.8.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:

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

    Если mysqld не связан статически, используйте следующую команду вместо этого:

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

    Если требуется декодировать символы C++, используйте --demangle, если доступно, для nm. Если у вашей версии nm нет этой опции, необходимо использовать команду c++filt после того, как дамп стека будет сгенерирован, для разбора имён C++.

  3. Выполните следующую команду:

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

    Если вы не смогли включить разбор имён C++ в свой файл символов, обработайте вывод resolve_stack_dump с помощью c++filt:

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

    Это выведет, где завершилась работа mysqld. Если это не поможет определить причину завершения работы mysqld, вы должны создать отчёт об ошибке и включить в него вывод из предыдущей команды.

    Однако в большинстве случаев трассировка стека недостаточно для определения причины проблемы. Чтобы найти ошибку или предоставить решение, в большинстве случаев нам нужна строка кода, которая привела к завершению работы mysqld, и желательно тестовый случай, чтобы мы могли воспроизвести проблему! См. Раздел 1.5, «Как сообщать об ошибках или проблемах».

Более новые версии функций трассировки стека glibc также выдают адрес как относительный к объекту. На системах, основанных на glibc (Linux), трассировка для неожиданного завершения работы плагина выглядит примерно так:

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

Для преобразования относительного адреса (+0x9a6) в имя файла и номер строки используйте эту команду:

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

Утилита addr2line входит в пакет binutils на Linux.

На Solaris процедура аналогична. Утилита трассировки стека Solaris printstack() уже выводит относительные адреса:

plugin/auth/auth_test_plugin.so:0x1510

Для преобразования используйте эту команду:

$> 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]

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/using-stack-trace.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API