作者:京东科技 孙晓军
1. GDB介绍
GDB是GNU Debugger的简称,其作用是可以在程序运行时,检测程序正在做些什么。GDB程序自身是使用C和C++程序编写的,但可以支持除C和C++之外很多编程语言的调试。GDB原生支持调试的语言包含:
•C
•C++
•D
•Go
•Object-C
•OpenCL C
•Fortran
•Pascal
•Rust
•Modula-2
•Ada
此外,通过扩展GDB,也可以用来调试Python语言。
使用GDB,我们可以方便地进行如下任务:
•如果程序崩溃后产生了core dump文件,gdb可以通过分析core dump文件,找出程序crash的位置,调用堆栈等用于找出问题原因的关键信息
•在程序运行时,GDB可以检测当前程序正在做什么事情
•在程序运行时,修改变量的值
•可以使程序在特定条件下中断
•监视内存地址变动
•分析程序Crash后的core文件
GDB是了解三方中间件,无源码程序,解决程序疑难杂症的利器。使用GDB,可以了解程序在运行时的方方面面。尤其对于在测试(Test),集成(SIT),验收(UAT),预发布(Staging)等环境下的问题调查和解决,GDB有着日志无法比拟的优势。此外,GDB还非常适合对多种开发语言混合的程序进行调试。
GDB不适合用来做什么:
•GDB可以用来辅助调试内存泄露问题,但GDB不能用于内存泄露检测
•GDB可以用来辅助程序性能调优,但GDB不能用于程序性能问题分析
•GDB不是编译器,不能运行有编译问题的程序,也不能用来调试编译问题
2. 安装GDB
2.1. 从已发布的二进制包安装
在基于Debian的Linux系统,可以使用apt-get命令方便地安装GDB
apt-get update
apt-get install gdb
2.2. 从源代码安装
前置条件
# 安装必要的编译工具
apt-get install build-essential
首先,我们需要下载GDB的源码。官网下载源码的地址是:
https://ftp.gnu.org/gnu/gdb/
# 下载源代码
wget http://ftp.gnu.org/gnu/gdb/gdb-9.2.tar.gz
# 解压安装包
tar -xvzf gdb-9.2.tar.gz
# 编译GDB
cd gdb-7.11
mkdir build
cd build
../configure
make
# 安装GDB
make install
# 检查安装结果
gdb --version //输出
3. 准备使用GDB
3.1. 在docker容器内使用GDB
GDB需要使用ptrace 方法发送PTRACE_ATTACH请求给被调试进程,用来监视和控制另一个进程。
Linux 系统使用
/proc/sys/kernel/yama/ptrace_scope设置来对ptrace施加安全控制。默认ptrace_scope的设置的值是1。默认设置下,进程只能通过PTRACE_ATTACH请求,附加到子进程。当设置为0时,进程可以通过PTRACE_ATTACH请求附加到任何其它进程。
在docker容器内,即使是root用户,仍有可能没有修改这个文件的权限。使得在使用GDB调试程序时会产生“ptrace: Operation not permitted “错误。
为了解决docker容器内使用GDB的问题,我们需要使用特权模式运行docker容器,以便获得修改
/proc/sys/kernel/yama/ptrace_scope文件的权限。
# 以特权模式运行docker容器
docker run --privileged xxx
# 进入容器,输入如下指令改变PTRACE_ATTACH请求的限制
echo 0 > /proc/sys/kernel/yama/ptrace_scope
3.2. 启用生成core文件
默认情况下,程序Crash是不生成core文件的,因为默认允许的core文件大小为0。
为了在程序Crash时,能够生成core文件来帮助排查Crash的原因,我们需要修改允许的core文件大小设置
# 查看当前core文件大小设置
ulimit -a
# 设置core文件大小为不限制
ulimit -c unlimited
# 关闭core文件生成功能
ulimit -c 0
修改core文件设置后,再次查看core文件的设置时,会看到下面的结果