一篇文章玩转GDB调试Redis源码

一、安装调试版redis

参考博客:https://success.blog.csdn.net/article/details/83659776

注意需要在makefile的开头定义CFLAGS 变量:CFLAGS = -g ,否则调试过程中无法跟踪代码

二、使用gdb启动redis-server

[why@whydeMacBook-Pro] ~$sudo gdb /usr/local/bin/redis-server /usr/local/etc/redis/redis_6379.conf 

会遇到如下问题:

(gdb) r 
Starting program: /usr/local/bin/redis-server 
Unable to find Mach task port for process-id 49363: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))

mac的签名问题,参考这篇文章解决:https://blog.csdn.net/LU_ZHAO/article/details/104803399

启动成功如下:

[why@whydeMacBook-Pro] ~$sudo gdb /usr/local/bin/redis-server /usr/local/etc/redis/redis_6379.conf 
GNU gdb (GDB) 8.3
Copyright (C) 2019 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-apple-darwin18.5.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://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 /usr/local/bin/redis-server...
"/usr/local/etc/redis/redis_6379.conf" is not a core dump: file format not recognized
(gdb)

三、GDB调试过程

追一下set命令的执行过程:

(gdb) b setCommand
Breakpoint 1 at 0x100035a7e: file t_string.c, line 102.
(gdb) c
(gdb) 

cli模式连接redis并执行set命令,此时程序会阻塞在这:

[why@whydeMacBook-Pro] /usr/local/bin$redis-cli 
127.0.0.1:6379> set why why

gdb交互输入n单步执行,c跳到下一个断点处

gdb focus开启可视化查看代码:

   ┌──t_string.c─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
   │90              if (expire) notifyKeyspaceEvent(NOTIFY_GENERIC,                                                                                  │
   │91                  "expire",key,c->db->id);                                                                                                     │
   │92              addReply(c, ok_reply ? ok_reply : shared.ok);                                                                                    │
   │93          }                                                                                                                                    │
   │94                                                                                                                                               │
   │95          /* SET key value [NX] [XX] [EX <seconds>] [PX <milliseconds>] */                                                                     │
   │96          void setCommand(client *c) {                                                                                                         │
   │97              int j;                                                                                                                           │
   │98              robj *expire = NULL;                                                                                                             │
   │99              int unit = UNIT_SECONDS;                                                                                                         │
   │100             int flags = OBJ_SET_NO_FLAGS;                                                                                                    │
   │101                                                                                                                                              │
B+>│102             for (j = 3; j < c->argc; j++) {                                                                                                  │
   │103                 char *a = c->argv[j]->ptr;                                                                                                   │
   │104                 robj *next = (j == c->argc-1) ? NULL : c->argv[j+1];                                                                         │
   │105                                                                                                                                              │
   │106                 if ((a[0] == 'n' || a[0] == 'N') &&                                                                                          │
   │107                     (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&                                                                          │
   │108                     !(flags & OBJ_SET_XX))                                                                                                   │
   │109                 {                                                                                                                            │
   │110                     flags |= OBJ_SET_NX;                                                                                                     │
   │111                 } else if ((a[0] == 'x' || a[0] == 'X') &&                                                                                   │
   │112                            (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&                                                                   │
   │113                            !(flags & OBJ_SET_NX))                                                                                            │
   │114                 {                                                                                                                            │
   │115                     flags |= OBJ_SET_XX;                                                                                                     │
   │116                 } else if ((a[0] == 'e' || a[0] == 'E') &&                                                                                   │
   └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
native Thread 0xf03 of pro In: setCommand                                                                                       L102  PC: 0x109ce7a7e 
warning: Invalid window specified.
The window name specified must be valid and visible.

Focus set to src window.
(gdb) 

接下来便可以一步步输入n向下追踪代码执行了。

 

gdb命令:https://man.linuxde.net/gdb

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页