写在文章开头
近期很多读者有询问有没有什么简单的办法快速上手调试redis,对此,笔者用到了Linux
系统中比较易上手的调试工具GDB
,本文将基于一个C语言两数交换的例子演示一下这款工具的使用。
Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili 。
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
详解GDB调试C代码过程
系统环境前置确认
请先确认自己Linux
服务器是否完成对g++
、gdb
、make
等工具的安装,因为笔者系统上安装的Ubuntu
系统,所以对应的检查和安装指令如下:
sudo apt-get update
sudo apt install g++ gdb make ninja-build rsync zip
两数交换代码示例
接下来便是编写C
语言代码了,笔者这里给出一个两数交换的例子test.c
文件,可以看到传入两个变量的指针,通过swap
函数完成两数交换
#include <stdio.h>
int main(void)
{
// 声明变量
int num1 = 10;
int num2 = 20;
//打印交换前的结果
printf("before swap num1 = %d, num2 = %d\n", num1, num2);
//传入两个变量的地址完成两数交换
swap(&num1, &num2);
//打印最终结果
printf("after swap num1 = %d, num2 = %d\n", num1, num2);
return 0;
}
//两数交换
void swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
我们通过gcc
指令进行编译并生成可执行文件:
gcc -g test.c -o test
随后我们通过./test
运行一下可执行文件,可以看到两数成功完成交换,运行结果正常:
before swap num1 = 10, num2 = 20
after swap num1 = 20, num2 = 10
启动GDB调试代码
基于上述示例,我们可以通过gdb调试并了解这段代码的工作流程,操作方式也比较简单,我们只需键入gdb 可执行文件名
,以笔者本次代码为例,就是gdb test
,如果正确执行就会输出下面这段内容,此时我们就可以看到一大段的加载信息:
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 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.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb)
当然,此时如果想退出,我们直接键入q键
即可:
如果你希望启动时不输出一大段文字,你也可以结合-q
指令启动调试:
调试步骤演示
基于上述步骤我们进入调试模式,和IDE
工具不同,终端调试工具无法一眼看到所有的代码,如果我们希望看到当前的代码信息,需要通过l即list
指令,例如笔者当前希望看到前10行的代码信息,那么我们就可以键入list
指令,此时我们就可以看到前10行代码内容了:
list
模式下,如果我们希望看到后续的代码段,只需不断键入回车或者键入l即继续向下查看代码:
了解了这个过程基本源码查看思路之后,我们就可以正式进入调试步骤了,假设我们此时希望在第13行代码打断点,那么我们可以键入b 13
当然我们也支持通过函数名打断点,例如我们希望在swap
函数上打断点,那么我们就可以键入b swap
:
在这期间,我们可键入info b (info breakpoint)
查看打到的断点:
对于不需要的断点,我们可以用d指令进行删除,例如断点2即对swap函数的断点我们不需要,可直接键入d 2
完成断点删除:
完成基本断点配置后,我们直接键入r
即可让代码跑起来,会直接执行到我们打断点的位置:
此时如果我们希望打印num1
的数值,可以通过p命令查看:
(gdb) p num1
$1 = 10
对于指针地址查看,也是一样的道理,还是以p1为例,我们直接键入p &num1
即可打印num1
地址:
(gdb) p &num1
$2 = (int *) 0x7fffffffdfd0
此时我们的代码已经执行到swap
函数了,如果我们希望查看其内部执行细节,可以直接键入s即step
步入:
(gdb) s
swap (x=0x7fffffffdfd0, y=0x7fffffffdfd4) at test.c:22
22 int tmp = *x;
后续我们可以不断键入n即next
让代码不断向下执行,在此期间我们可以结合上述说的p指令查看变量的变化:
如果我们希望结束当前层级的函数调用,可以直接键入finish,可以看到代码直接跳到swap
函数后面:
完成代码调试后,我们不再想调试后面的代码,可直接键入c
即continue
结束指令,如下所示,输出了当前程序的最终执行结果:
终端可视化TUI
上述操作在调试上没有全局的视角所以调试时很不直观,所以我们日常调试时可以键入tui选项(terminal ui)
指令进行调试,这里笔者直接以redis为例,编译成功后直接进入src
目录键入如下指令:
gdb -q -tui redis-server
最终呈现的调试界面就如下图所示,对应的指令上文已经介绍了这里就不多做赘述了:
小结
以上便是笔者对于gdb调试redis源码的快速上手教程,希望对你有帮助。
我是 sharkchili ,CSDN Java 领域博客专家,开源项目—JavaGuide contributor,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili 。
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
参考
Linux | 调试器GDB的详细教程【纯命令行调试】
:https://blog.csdn.net/Fire_Cloud_1/article/details/129213449
【Linux】GDB调试教程(新手小白)
:https://blog.csdn.net/lovely_dzh/article/details/109160337