前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术分享 | 数据库源码学习调试利器之 CGDB

技术分享 | 数据库源码学习调试利器之 CGDB

作者头像
爱可生开源社区
发布2024-10-15 12:42:13
1120
发布2024-10-15 12:42:13
举报
文章被收录于专栏:爱可生开源社区

作者:赵黎明,爱可生 MySQL DBA 团队成员,熟悉 Oracle、MySQL 等数据库,擅长数据库性能问题诊断、事务与锁问题的分析等,负责处理客户 MySQL 及我司自研 DMP 平台日常运维中的问题,对开源数据库相关技术非常感兴趣。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 2000 字,预计阅读需要 10 分钟。


1简介

CGDB (Curses-based GDB)[1]:是一个基于文本界面的 GDB[2] 前端,主要用于在终端中提供更丰富的用户界面,CGDB 使用 Curses 库[3] 创建了一个简单的功能界面,帮助用户更方便地使用 GDB,它在 GDB 的基础上增加了一些功能,使得调试过程更加直观和高效。

CGDB 的运行依赖 GDB 环境,因此,在调试前必须先安装符合其版本要求的 GDB

简单来说,CGDB 是 GDB 的一个前端工具,通过提供更丰富的界面来增强 GDB 的用户体验。如果更喜欢在增强型终端中操作,可以使用 CGDB 来代替 GDB。

2版本选择

本次选择安装 gdb 9.2 的版本,原因主要有以下两个:

  1. CentOS 7.5 中自带 gdb 的版本 7.6.1-120.el7,而 cgdb 要求 gdb 版本为 7.12 及以上。
  2. 安装 gdb 9.0 以上版本的,还可以用于调试 OBServer,否则会报版本错误。

3安装 CGDB

安装步骤:

代码语言:javascript
复制
-- 安装依赖
yum -y install automake flex texinfo ncurses-devel readline-devel gcc-c++

-- 下载源码包
git clone https://github.com/cgdb/cgdb.git

-- 编译源码
cd cgdb
./autogen.sh
./configure --prefix=/usr/local
make && make install

如果在执行 make 时报错:error: ‘for’ loop initial declarations are only allowed in C99 mode,可在进行编译配置时加上参数:CFLAGS="-std=c99",如:CFLAGS="-std=c99" ./configure --prefix=/usr/local

4安装 GDB

注意事项:

  • 尽量不装 10.x 及以上的高版本。可能会报错:A compiler with support for C++11 language features is required
  • CentOS 7.5 默认的 gcc 版本较低(4.8.5),原则上只要够用就行,没必要追求高版本。

安装步骤:

代码语言:javascript
复制
-- 安装依赖
yum -y install gcc gcc-c++ texinfo

-- 下载源码包
wget ftp://ftp.gnu.org/gnu/gdb/gdb-9.2.tar.gz

-- 解压并编译
tar zxf gdb-9.2.tar.gz -C /tmp
cd /tmp/gdb-9.2
mkdir build && cd build
/tmp/gdb-9.2/configure
make && make install

查看 gdb 的版本,确认是否升级成功。

执行 cgdb,进入调试界面。

5查看帮助

  • 键入 help + 回车键,可查看所有的 gdb 的指令和说明
  • 键入 ESC + :help + 回车键,可查看所有 cgdb 的指令和说明

具体指令和说明不在文中展示。

下面我们通过几个常用的场景示例,演示 CGDB 和 GDB 的使用过程和效果。

6调试示例

示例 1:调试 MySQL 获取源码

查看 mysqld 的进程号,此处为 26238。

在 gdb 窗口执行 att 26238,将其 attach 到 mysqld 进程上。

绿色箭头代表代码当前执行的位置,会展示代码所处行号,内存地址,代码文件等信息。

按 ESC 键,会进入上半部分的代码展示窗口,能像在 vim 中那样用快捷键上下移动光标进行查看。

如果要返回 gdb 的窗口,按 i 键即可,就能继续执行调试命令了。

根据打印的源码文件和位置,去官网代码库中找到对应的文件,再搜索相应的函数,就可以获取对应的源码内容了。

示例 2:调试 MySQL 线程

执行 info threads,打印所有线程。

依次执行 threadbt,查看当前线程及该线程的 backtrace。

多次执行 s,一行一行地进行单步调试,注意调试期间 thread 是否发生变化。

当前为 ID 1 的线程,如果要切换到某个 thread,可以执行 thread [thread_id] 进行切换。

以下是 49 号线程打印的 backtrace 信息示例,可获取函数调用的顺序、调用的函数名、函数出现在源码文件中的位置。

示例 3:使用 cgdb ./mysqld 调试

采用此方式调试 mysqld 时,当其还未被 attach 到 mysqld 上时,并不会阻塞新的连接。

此时只能设置断点,查看某个函数在源码文件中的位置。

由于没有线程及其帧栈信息,并不能做进一步的调试。

示例 4:分析 coredump 文件

当程序异常崩溃时,如果配置过 coredump,就可以通过分析 coredump 文件来排查程序崩溃的原因。

第一个 coredump,是通过执行 kill -SIGSEGV [pid] (也就是 signal 11)将 mysqld 进程杀死后产生的,其实从文件命名上就可获知,mysqld-11 后面紧跟的这个 11,就是对应信号量的编号。

在 cgdb 中也打印了 mysqld 崩溃的原因,是收到了 SIGSEGV(11) 的信号量,即最常见的 Segmentaion fault

第二个 coredump,是在用 cgdb 调试时生成的,期间执行过 run 命令,将 mysqld 进程重启过,产生了 mysqld-5 的 coredump 文件。

在 cgdb 中也打印了 mysqld 崩溃的原因,是收到了 SIGTRAP(5) 的信号量。

如果对信号量不太熟悉,可用 kill -l 命令查看,它会输出所有信号量。

示例 5:使用 cgdb -p 调试

与之前先进入 cgdb 调试台,再执行 attach [pid] 的方式并无区别,后者会在 cgdb/gdb 进程中显示 mysqld 进程号。

要注意的是,这两种方式都会直接阻塞 mysql 客户端,因为此时 mysqld 会被阻塞,导致无法建立新的连接。

用 SIGSTOP/SIGCONT 的信号量来观测效果

Tips:信号量名中的 SIG 是可以被省略的,如:kill -SIGSTOP [pid]kill -STOP [pid] 是等效的。

示例 6:单独起一个 mysqld 调试

该方式可以在不影响已运行 mysqld 的基础上,对同版本的 mysqld 单独进行调试。

建议下载带 boost 的 MySQL 源码包,然后编译为 Debug 版本,可以打印更多的 debugging symbols 信息,方便调试。

示例 7:修改 MySQL 最大连接数

当 MySQL 的连接数满导致无法登陆实例时,可以用 cgdb 来救急。

下图中,当客户端连接实例时报错:"Too many connections",直接用 cgdb/gdb 来调大 max_connections 参数的值。

如果服务器上有多个 mysqld 进程时,建议直接指定 pid,否则可能改到了另一个 MySQL 实例上。

用 cgdb 修改
用 gdb 修改

7总结

  • 本文简单介绍了 CGDB 及其基本使用方法。
  • 利用 CGDB 调试工具,能帮助我们梳理程序在运行时各种函数的调用逻辑,这对于学习和研究程序源码非常有帮助。
  • 当程序崩溃时,如果能拿到故障现场的 coredump 文件,可通过 CGDB 去分析程序崩溃的原因,如:在特定场景下,在调用某个函数时触发了程序的 bug 而引发的崩溃。
  • 当 MySQL 连接数被打满后,除了我们已知的 extra_port 方法之外,还可以用 CGDB 来解决。
  • 注意,生产环境严禁使用 CGDB 直接进行调试。

参考资料

[1]

CGDB: https://cgdb.github.io/

[2]

GDB: https://sourceware.org/gdb/

[3]

curses-library: https://www.ibm.com/docs/zh/aix/7.3?topic=concepts-curses-library

本文关键字:#CGDB# #GDB# #调试工具# #源码#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1简介
  • 2版本选择
  • 3安装 CGDB
  • 4安装 GDB
  • 5查看帮助
  • 6调试示例
    • 示例 1:调试 MySQL 获取源码
      • 示例 2:调试 MySQL 线程
        • 示例 3:使用 cgdb ./mysqld 调试
          • 示例 4:分析 coredump 文件
            • 示例 5:使用 cgdb -p 调试
              • 示例 6:单独起一个 mysqld 调试
                • 示例 7:修改 MySQL 最大连接数
                  • 用 cgdb 修改
                  • 用 gdb 修改
              • 7总结
                • 参考资料
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档