gdb调试redis源码(附vscode调试redis)
前置知识gdbgdb几种设置断点的方式方式1、根据函数名,查找符号(symbol)设置断电例子:b func_name方式2、根据代码行位置设置断点例子:b /src/filename.c:81。gdb将在运行到源码文件/src/filename.c的第81行中断方式3、根据运行时的地址设置断点此时有两种方式,一是通过直接指定地址进行,进行断点设置。二是通过print命令获得相关信息例子1:b 0
前置知识gdb
gdb几种设置断点的方式
-
方式1、根据函数名,查找符号(symbol)设置断电
例子:b func_name -
方式2、根据代码行位置设置断点
例子:b /src/filename.c:81。gdb将在运行到源码文件/src/filename.c的第81行中断 -
方式3、根据运行时的地址设置断点
此时有两种方式,一是通过直接指定地址进行,进行断点设置。二是通过print命令获得相关信息
例子1:b 0x5859c0。""号是必须加在地址前的,0x5859c0为函数指针的地址
例子2:展示变量内容
(gdb) p *thread_scheduler
gdb参数设置:https://blog.csdn.net/weixin_33695450/article/details/90184857
gdb调试layout的使用:https://blog.csdn.net/zhangjs0322/article/details/10152279
gcc 编译选项中 -O0 -g ,-O3 对程序效率影响很大 。如果是 -O0 -g 编译非优化,会添加调试信息,编译完成后可执行程序非常大,运行效率也会很慢。所以如果自己线下调试程序,可以用-O0 -g,但线上发布时一定要用-O3开启优化选项。
linux上用gdb调试redis源码
打开ubuntu的终端操作如下:
安装redis
先下载redis的源码并安装可直接参考官网: redis quickstart
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
## 测试redis是否安装成功
redis-server
## 出现如下即已安装成功
7854:C 03 Jul 17:54:03.179 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7854:C 03 Jul 17:54:03.179 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=7854, just started
7854:C 03 Jul 17:54:03.180 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
7854:M 03 Jul 17:54:03.183 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.10 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 7854
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
7854:M 03 Jul 17:54:03.192 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7854:M 03 Jul 17:54:03.193 # Server initialized
7854:M 03 Jul 17:54:03.194 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
7854:M 03 Jul 17:54:03.198 * DB loaded from disk: 0.000 seconds
7854:M 03 Jul 17:54:03.219 * Ready to accept connections
安装gdb
sudo apt-get install gdb
使用gdb debug redis源码
## 为了调试,在编译redis的源码的时候需要带上参数
make CFLAGS="-g -O0"
## 如果之前已经编译过的话,可以删掉makefile文件重新编译即可。
## 执行如下命令
gdb redis-server
## 即可进入gdb的模式 如下:
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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:
<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 redis-server...done.
(gdb)
## 先设置一个断点,并运行至该点断的位置,gdb支持断点到方法,如下:断点在main方法、并运行至该断点。
(gdb) b main
Breakpoint 1 at 0x433700: file server.c, line 3704.
(gdb) r
Starting program: /usr/local/bin/redis-server
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main (argc=1, argv=0x7ffffffee1b8) at server.c:3704
3704 int main(int argc, char **argv) {
(gdb)
至此已经进入了debug的模式,并且现在的停留在server.c的main方法中,为了看的更方便可以执行如下命令进入多窗口模式可以边看源码边调试,还有一些其他命令的用法可以参考 Debugging with GDB 和 gdb 调试利器
## 进入多窗口模式
(gdb) layout src
## 简单调试的基本用法
## 进入下一步next简写n
(gdb) n
## 进入方法里面 step,如下进入就是setproctitle.c中的spt_init方法里
(gdb) step
spt_init (argc=1, argv=0x7ffffffee1b8) at setproctitle.c:153
## 打印当前的一些变量值
(gdb) p argc
$1 = 1
## 跳出当前方法
(gdb) finish
## 当然还有很多更高级的用法,自行参考官网,或者使用help命令查看一些说明,在或者google
(gdb) help
到此就是整个简单使用gdb来调试redis源码的基本流程。下面我们就用gdb来试着调试一下sentinel模式将运行的代码。
准备调试redis配置文件和启动命令
搭建sentinel的模型,目标3个sentinel,1个主服务器,2个从服务器。
详细搭建教程可参考:Replication
配置1主2从
## 配置一主两从的结构 创建一个配置文件夹
$ sudo mkdir /svr/redis_config
$ sudo cp /svr/redis-stable/redis.conf /svr/redis_config/redis_6379.conf
$ cd /svr/redis_config
$ sudo cp redis_6379.conf redis_6380.conf
$ sudo cp redis_6379.conf redis_6381.conf
$ sudo vim redis_6379.conf
$ sudo vim redis_6380.conf
$ sudo vim redis_6381.conf
分别修改端口号和pid文件名和后台进程启动
## 以6380文件为例,修改如下几个值
port 6380
daemonize yes
slaveof 127.0.0.1 6379
pidfile /var/run/redis_6380.pid
## 保存之后退出,依次修改另一个文件,启动redis实例
$ sudo redis-server /svr/redis_config/redis_6379.conf
$ sudo redis-server /svr/redis_config/redis_6380.conf
$ sudo redis-server /svr/redis_config/redis_6381.conf
## 另外一种配置的从库方法就是客户端连上从库之后发送如下命令即可
$ sudo redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379
至此redis的主从就搭建好了.可以通过redis-cli
连接发送info
命令查看服务器状态信息
搭建三个sentinel
更多的配置细节参考:官网topic之sentinel
## 拷贝sentinel文件
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26379.conf
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26380.conf
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26381.conf
$ sudo vim /svr/redis_config/sentinel_26379.conf
## 同样修改配置如下内容,以26380为例,其中dir为工作路径,请在启动前请确保此文件夹存在。
## sentinel的myid在三个文件中请一定要配置不同,因为这个值代表这个sentinel的runid。配置监听的主服务器和选票的数量。
port 26380
daemonize yes
dir "/svr/redis_config/sentinel_26380/tmp"
sentinel myid 672268275d7a8a9809acaa83ecc4f63dce39fc5a
sentinel monitor mymaster 127.0.0.1 6379 2
## 保存退出后启动应用
$ sudo redis-sentinel /svr/redis_config/sentinel_26379.conf
$ sudo redis-sentinel /svr/redis_config/sentinel_26380.conf
$ sudo redis-sentinel /svr/redis_config/sentinel_26381.conf
## 也可以用sentinel模式,如:
$ sudo redis-server sentinel_26381.conf --sentinel
至此三个sentinel已经搭建好了
## 客户端连接查看sentinel是否已经相互连接,使用info命令便可以看到详细信息
$ sudo redis-cli -p 26379
127.0.0.1:26379> info
# Server
redis_version:4.0.10
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:564e829c2a2c36f6
redis_mode:sentinel
os:Linux 4.4.0-17134-Microsoft x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:5.4.0
process_id:8472
run_id:3d6ee9716c852c234bdb61515372046396adb0b9
tcp_port:26379
uptime_in_seconds:35
uptime_in_days:0
hz:11
lru_clock:3907301
executable:/svr/redis_config/redis-sentinel
config_file:/svr/redis_config/sentinel_26379.conf
# Clients
connected_clients:3
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# CPU
used_cpu_sys:0.02
used_cpu_user:0.02
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Stats
total_connections_received:3
total_commands_processed:75
instantaneous_ops_per_sec:1
total_net_input_bytes:3904
total_net_output_bytes:484
instantaneous_input_kbps:0.02
instantaneous_output_kbps:0.01
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
从最后一行我们可以看到整个网络架构已经建立好了。
## 也可以用如下命令查看sentinels 信息
127.0.0.1:26379> sentinel sentinels mymaster
1) 1) "name"
2) "672268275d7a8a9809acaa83ecc4f63dce39fc5b"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "26381"
7) "runid"
8) "672268275d7a8a9809acaa83ecc4f63dce39fc5b"
9) "flags"
10) "sentinel"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "488"
19) "last-ping-reply"
20) "488"
21) "down-after-milliseconds"
22) "30000"
23) "last-hello-message"
24) "259"
25) "voted-leader"
26) "?"
27) "voted-leader-epoch"
28) "0"
2) 1) "name"
2) "672268275d7a8a9809acaa83ecc4f63dce39fc5a"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "26380"
7) "runid"
8) "672268275d7a8a9809acaa83ecc4f63dce39fc5a"
9) "flags"
10) "sentinel"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "488"
19) "last-ping-reply"
20) "488"
21) "down-after-milliseconds"
22) "30000"
23) "last-hello-message"
24) "562"
25) "voted-leader"
26) "?"
27) "voted-leader-epoch"
28) "0"
调试sentinel的相关代码
结合前面简单的调试和sentinel的配置文件,我们可以使用gdb来启动一个sentinel从main方法来开始调试。
## 先关掉一个sentinel
$ ps -aux|grep redis
root 7995 0.0 0.0 45636 2356 ? Ssl Jul03 0:01 redis-server 127.0.0.1:6379
root 8046 0.0 0.0 45636 2096 ? Ssl Jul03 0:00 redis-server 127.0.0.1:6380
root 8054 0.0 0.0 45636 2092 ? Ssl Jul03 0:01 redis-server 127.0.0.1:6381
jane-zh+ 8267 0.0 0.0 16224 260 tty3 S Jul03 0:00 redis-cli -p 26379
root 8286 0.0 0.0 14892 576 tty4 S Jul03 0:00 sudo redis-cli -p 26380
root 8287 0.0 0.0 16224 256 tty4 S Jul03 0:00 redis-cli -p 26380
root 8472 0.0 0.0 43588 2800 ? Ssl 00:05 0:00 redis-sentinel *:26379 [sentinel]
root 8478 0.0 0.0 43588 2704 ? Ssl 00:05 0:00 redis-sentinel *:26380 [sentinel]
root 8484 0.0 0.0 43588 2720 ? Ssl 00:05 0:00 redis-sentinel *:26381 [sentinel]
root 8488 0.0 0.0 14656 2120 tty2 S 00:05 0:00 sudo redis-cli -p 26379
root 8489 0.0 0.0 16224 1284 tty2 S 00:05 0:00 redis-cli -p 26379
jane-zh+ 8491 0.0 0.0 12892 1112 tty5 S 00:18 0:00 grep --color=auto redis
$ sudo kill -9 8472
## 使用gdb启动redis-sentinel命令
$ sudo gdb redis-sentinel
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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:
<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 redis-sentinel...done.
(gdb) b main
Breakpoint 1 at 0x433700: file server.c, line 3704.
(gdb) r /svr/redis_config/sentinel_26379.conf
Starting program: /usr/local/bin/redis-sentinel /svr/redis_config/sentinel_26379.conf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main (argc=2, argv=0x7ffffffee698) at server.c:3704
3704 int main(int argc, char **argv) {
(gdb) layout src
至此便可以愉快的开始从头调试sentinel的代码,调试步骤依然像前面简单介绍的一样。下篇便是开始总结redis的sentinel。
vscode调试redis
流程参照链接:https://blog.csdn.net/m0_37731056/article/details/106182202
vscode调试redis源码配置:
.vscode/task.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "build-redis",
"command": "/usr/bin/make",
"args": [
"CFLAGS=\"-g -O0\""
],
"options": {
"cwd": "${workspaceFolder}/src"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind":"build",
"isDefault":true
},
"detail": "调试器生成的任务"
}
]
}
.vscode/launch.json
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/redis-server",
"args": ["redis.conf"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask":"build-redis",
"miDebuggerPath":"/usr/bin/gdb"
}
]
}
更多推荐
所有评论(0)