翼度科技»论坛 编程开发 mysql 查看内容

从零开始学习MySQL调试跟踪(1)

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24

  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
  • GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
  • 作者:  Yejinrong/叶金荣
  • 文章来源:GreatSQL社区投稿



    • 编译GreatSQL


    • 安装gdb


    • 开始调试GreatSQL源码


    • 3.1 利用gdb设置断点
    • 3.2 使用 Trace 文件调试

有时为了跟踪故障需要调试MySQL/GreatSQL源码,本文介绍如何在Linux下构建MySQL/GreatSQL源码调试环境。
在这之前,我也是一名小白,一起从零开始探索吧。
本文以CentOS 8.x环境下的GreatSQL 8.0.25-16版本为例。
1. 编译GreatSQL

查看系统环境:
  1. $ cat /etc/system-release
  2. CentOS Linux release 8.4.2105
复制代码
首先,从https://gitee.com/GreatSQL/GreatSQL/releases/ 下载GreatSQL 8.0.25-16的源码包

  • Source Code
PackagesSizegreatsql-8.0.25-16.tar.gz503M
接下来,参考文章 在Linux下源码编译安装GreatSQL 构建好编译环境。然后开始编译GreatSQL源码,编译参数中增加/修改debug相关选项,这样编译后得到的二进制文件才能支持调试模式,例如:
  1. $ cd /opt/greatsql-8.0.25-16
  2. $ mkdir -p build
  3. $ cd build
  4. $ cmake3 .. \
  5. -DBOOST_INCLUDE_DIR=/opt/boost_73_0 \
  6. -DLOCAL_BOOST_DIR=/opt/boost_73_0 \
  7. -DCMAKE_INSTALL_PREFIX=/usr/local/GreatSQL-8.0.25-16-Linux-glibc2.28-x86_64 \
  8. -DWITH_ZLIB=bundled \
  9. -DWITH_NUMA=ON \
  10. -DCMAKE_EXE_LINKER_FLAGS="-ljemalloc" \
  11. -DBUILD_CONFIG=mysql_release \
  12. -DWITH_TOKUDB=OFF \
  13. -DWITH_ROCKSDB=OFF \
  14. -DMAJOR_VERSION=8 \
  15. -DMINOR_VERSION=0 \
  16. -DPATCH_VERSION=25 \
  17. -DWITH_UNIT_TESTS=OFF \
  18. -DWITH_NDBCLUSTER=OFF \
  19. -DWITH_SSL=system \
  20. -DWITH_SYSTEMD=ON \
  21. -DWITH_LDAP=OFF \
  22. -DWITH_AUTHENTICATION_LDAP=OFF \
  23. -DWITH_DEBUG=1 \
  24. -DCMAKE_BUILD_TYPE=Debug \
  25. && make -j8 VERBOSE=1 && make install
复制代码
主要是增加两个参数 -DWITH_DEBUG=1 和 -DCMAKE_BUILD_TYPE=Debug,注意不要有参数 -DCMAKE_BUILD_TYPE=RelWithDebInfo。
编译完成后,即可得到包含debug功能的GreatSQL二进制文件,执行下面的命令检查:
  1. $ cd /usr/local/GreatSQL-8.0.25-16-Linux-glibc2.28-x86_64
  2. $ ./bin/mysqld-debug --verbose --version
  3. /usr/local/GreatSQL-8.0.25-16-Linux-glibc2.28-x86_64/bin/mysqld-debug  Ver 8.0.25-16-debug for Linux on x86_64 (Source distribution)
复制代码
可以看到,输出的结果中包含 debug 关键字,这就表示成功了。
2. 安装gdb

直接执行yum安装gdb即可:
  1. $ yum install -y gdb
  2. $ gdb --version
  3. GNU gdb (GDB) Red Hat Enterprise Linux 9.2-4.el8
  4. Copyright (C) 2020 Free Software Foundation, Inc.
  5. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  6. This is free software: you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law.
复制代码
gdb常用的调试相关指令有以下几个:
命令缩写备注attach挂接/进入准备调试的进程piddetach取消挂接进程(退出进程)listl显示多行源代码breakb设置断点,程序运行到断点的位置会停下来infoi描述程序的状态runr开始运行程序displaydisp跟踪查看某个变量,每次停下来都显示它的值steps执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句nextn执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)printp打印内部变量值continuec继续程序的运行,直到遇到下一个断点set var name=v设置变量的值startst开始执行程序,在main函数的第一条语句前面停下来file装入需要调试的程序killk终止正在调试的程序watch监视变量值的变化backtracebt查看函数调用信息(堆栈)framef查看栈帧quitq退出gdb3. 开始调试GreatSQL源码

第一次运行gdb准备调试时,可能会提示类似下面的信息
  1. warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  2. 0x00007ffb358ada41 in poll () from /lib64/libc.so.6
  3. Missing separate debuginfos, use: dnf debuginfo-install keyutils-libs-1.5.10-9.el8.x86_64 ...
复制代码
这表示缺少一些相关的debuginfo包,可以根据提示内容补充安装,例如:
  1. dnf debuginfo-install keyutils-libs-1.5.10-9.el8.x86_64 ...
复制代码
如果提示找不到这些安装包:
  1. Could not find debuginfo package for the following installed packages: keyutils-libs-1.5.10-9.el8.x86_64 ...
复制代码
可以检查yum配置文件 /etc/yum.repos.d/CentOS-Linux-Debuginfo.repo,确认是否设置了 enable = 1,例如:
  1. # CentOS-Linux-Debuginfo.repo
  2. #
  3. # All debug packages are merged into a single repo, split by basearch, and are
  4. # not signed.
  5. [debuginfo]
  6. name=CentOS Linux $releasever - Debuginfo
  7. baseurl=http://debuginfo.centos.org/$releasever/$basearch/
  8. gpgcheck=1
  9. enabled=1    #<---这里要设置1
  10. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
复制代码
启动gdb,准备调试跟踪GreatSQL,我们分别演示几种不同方式。
3.1 利用gdb设置断点

在 终端#1 中启动gdb,并挂接GreatSQL进程,准备跟踪
  1. $ tar zxf PATH/greatsql-8.0.25-16.tar.gz -C /opt/
复制代码
查看生成的trace文件:
[code]$ cat /tmp/mysqld.trace...>do_command| >THD::clear_error| Diagnostics_area::reset_diagnostics_area| my_net_set_read_timeout| | enter: timeout: 28800| | >vio_socket_timeout| | vio_read| | | >vio_is_blocking| | | vio_io_wait| | | THD::clear_error   sql_class.h: | Diagnostics_area::reset_diagnostics_area  sql_error.cc: | my_net_set_read_timeout   net_serv.cc:  2247: | | enter: timeout: 28800  viosocket.cc:   380: | | >vio_socket_timeout  viosocket.cc: | | vio_read  viosocket.cc:   373: | | | >vio_is_blocking  viosocket.cc: | | | vio_io_wait  viosocket.cc: | | |

举报 回复 使用道具