|
- GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
- GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
- 作者: Yejinrong/叶金荣
- 文章来源:GreatSQL社区投稿
- 3.1 利用gdb设置断点
- 3.2 使用 Trace 文件调试
有时为了跟踪故障需要调试MySQL/GreatSQL源码,本文介绍如何在Linux下构建MySQL/GreatSQL源码调试环境。
在这之前,我也是一名小白,一起从零开始探索吧。
本文以CentOS 8.x环境下的GreatSQL 8.0.25-16版本为例。
1. 编译GreatSQL
查看系统环境:- $ cat /etc/system-release
- CentOS Linux release 8.4.2105
复制代码 首先,从https://gitee.com/GreatSQL/GreatSQL/releases/ 下载GreatSQL 8.0.25-16的源码包
PackagesSizegreatsql-8.0.25-16.tar.gz503M 接下来,参考文章 在Linux下源码编译安装GreatSQL 构建好编译环境。然后开始编译GreatSQL源码,编译参数中增加/修改debug相关选项,这样编译后得到的二进制文件才能支持调试模式,例如:- $ cd /opt/greatsql-8.0.25-16
- $ mkdir -p build
- $ cd build
- $ cmake3 .. \
- -DBOOST_INCLUDE_DIR=/opt/boost_73_0 \
- -DLOCAL_BOOST_DIR=/opt/boost_73_0 \
- -DCMAKE_INSTALL_PREFIX=/usr/local/GreatSQL-8.0.25-16-Linux-glibc2.28-x86_64 \
- -DWITH_ZLIB=bundled \
- -DWITH_NUMA=ON \
- -DCMAKE_EXE_LINKER_FLAGS="-ljemalloc" \
- -DBUILD_CONFIG=mysql_release \
- -DWITH_TOKUDB=OFF \
- -DWITH_ROCKSDB=OFF \
- -DMAJOR_VERSION=8 \
- -DMINOR_VERSION=0 \
- -DPATCH_VERSION=25 \
- -DWITH_UNIT_TESTS=OFF \
- -DWITH_NDBCLUSTER=OFF \
- -DWITH_SSL=system \
- -DWITH_SYSTEMD=ON \
- -DWITH_LDAP=OFF \
- -DWITH_AUTHENTICATION_LDAP=OFF \
- -DWITH_DEBUG=1 \
- -DCMAKE_BUILD_TYPE=Debug \
- && make -j8 VERBOSE=1 && make install
复制代码 主要是增加两个参数 -DWITH_DEBUG=1 和 -DCMAKE_BUILD_TYPE=Debug,注意不要有参数 -DCMAKE_BUILD_TYPE=RelWithDebInfo。
编译完成后,即可得到包含debug功能的GreatSQL二进制文件,执行下面的命令检查:- $ cd /usr/local/GreatSQL-8.0.25-16-Linux-glibc2.28-x86_64
- $ ./bin/mysqld-debug --verbose --version
- /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即可:- $ yum install -y gdb
- $ gdb --version
- GNU gdb (GDB) Red Hat Enterprise Linux 9.2-4.el8
- Copyright (C) 2020 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
- This is free software: you are free to change and redistribute it.
- 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准备调试时,可能会提示类似下面的信息- warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
- 0x00007ffb358ada41 in poll () from /lib64/libc.so.6
- Missing separate debuginfos, use: dnf debuginfo-install keyutils-libs-1.5.10-9.el8.x86_64 ...
复制代码 这表示缺少一些相关的debuginfo包,可以根据提示内容补充安装,例如:- dnf debuginfo-install keyutils-libs-1.5.10-9.el8.x86_64 ...
复制代码 如果提示找不到这些安装包:- 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,例如:- # CentOS-Linux-Debuginfo.repo
- #
- # All debug packages are merged into a single repo, split by basearch, and are
- # not signed.
- [debuginfo]
- name=CentOS Linux $releasever - Debuginfo
- baseurl=http://debuginfo.centos.org/$releasever/$basearch/
- gpgcheck=1
- enabled=1 #<---这里要设置1
- gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
复制代码 启动gdb,准备调试跟踪GreatSQL,我们分别演示几种不同方式。
3.1 利用gdb设置断点
在 终端#1 中启动gdb,并挂接GreatSQL进程,准备跟踪- $ 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: | | | |
|