关于T_string.c简单的调试 准备两台centos7的虚拟机, 10.100.13.160 作为redis服务器 10.10.13.81 作为redis客户端 共享Windows目录到10.100.13.160,方便查看和修改 mount -t cifs //10.100.13.123/mysourcecode /mysourcecode -o username=Everyone,file_mode=0777,dir_mode=0777 编译redis服务器的时候,增加编译参数 CFLAGS = -g -O0 0这个级别表示编译时没有优化,方便查看源代码 gcc -v 升级到gcc 9: yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils 临时解决 scl enable devtoolset-9 bash 永久解决 echo “source /opt/rh/devtoolset-9/enable” >>/etc/profile 编译过程出现的错误和解决方法 问题1 Increased maximum number of open files to 10032 (it was originally set to 256) 查看设置的值 ulimit -a 重新设置值 ulimit -n 10032 问题2 The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 临时解决 echo 2048> /proc/sys/net/core/somaxconn 永久解决 在/etc/sysctl.conf中添加如下 net.core.somaxconn = 2048 然后在终端中执行 sysctl -p 问题3 # 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. 处理可以同问题2 结果如图示 [root@localhost redis]# cat /etc/sysctl.conf # System default settings live in /usr/lib/sysctl.d/00-system.conf. # To override those settings, enter new settings here, or in an /etc/sysctl.d/<name>.conf file # # For more information, see sysctl.conf(5) and sysctl.d(5). net.core.somaxconn = 2048 vm.overcommit_memory = 1 问题4 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. [root@localhost ~]# vi /etc/rc.local [root@localhost ~]# cat /etc/rc.local #!/bin/bash # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES # # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # # In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. # # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure # that this script will be executed during boot. touch /var/lock/subsys/local echo never > /sys/kernel/mm/transparent_hugepage/enabled 调试中出现的提示 问题1 Missing separate debuginfos, use: debuginfo-install glibc-2.17-324.el7_9.x86_64 /etc/yum.repos.d/CentOS-Debuginfo.repo 1设置/etc/yum.repos.d/CentOS-Debuginfo.repo 文件的 enable=1 [root@localhost ae]# cat /etc/yum.repos.d/CentOS-Debuginfo.repo # CentOS-Debug.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # All debug packages from all the various CentOS-7 releases # are merged into a single repo, split by BaseArch # # Note: packages in the debuginfo repo are currently not signed # [base-debuginfo] name=CentOS-7 - Debuginfo baseurl=http://debuginfo.centos.org/7/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-7 enabled=1 2 执行yum install -y glibc 3 执行debuginfo-install glibc 安装debuginfo相关的包步骤如下: 1、 修改文件/etc/yum.repos.d/CentOS-Debuginfo.repo中的enabled参数,将其值修改为1 2、 使用命令: yum install nss-softokn-debuginfo –nogpgcheck yum install yum-utils gdb启动服务端 1.gdb ./src/redis-server 2.添加参数 set args ./redis.conf 3.查看所需添加断点的代码,比如我想查看增加键值的代码 l incrDecrCommand 然后添加断点 b incrDecrCommand gdb启动客户端 1.gdb ./redis-cli 2 设置参数 (gdb) set args -h 10.100.13.160 3启动 (gdb) start 4测试键值加1操作 10.100.13.160:6379> incr test1 此时服务端的情况 Breakpoint 1, incrDecrCommand (c=0x7ffff6d4d100, incr=1) at t_string.c:350 350 o = lookupKeyWrite(c->db,c->argv[1]); (gdb) bt #0 incrDecrCommand (c=0x7ffff6d4d100, incr=1) at t_string.c:350 #1 0x00000000004672c4 in incrCommand (c=0x7ffff6d4d100) at t_string.c:385 #2 0x000000000043873a in call (c=0x7ffff6d4d100, flags=15) at server.c:3295 #3 0x0000000000439674 in processCommand (c=0x7ffff6d4d100) at server.c:3679 #4 0x000000000044ab20 in processCommandAndResetClient (c=0x7ffff6d4d100) at networking.c:1785 #5 0x000000000044ad73 in processInputBuffer (c=0x7ffff6d4d100) at networking.c:1867 #6 0x000000000044b120 in readQueryFromClient (conn=0x7ffff6c150c0) at networking.c:1950 #7 0x00000000004e66e3 in callHandler (conn=0x7ffff6c150c0, handler=0x44adf3 <readQueryFromClient>) at connhelpers.h:79 #8 0x00000000004e6d70 in connSocketEventHandler (el=0x7ffff6c0b480, fd=12, clientData=0x7ffff6c150c0, mask=1) at connection.c:281 #9 0x000000000042fa1f in aeProcessEvents (eventLoop=0x7ffff6c0b480, flags=27) at ae.c:479 #10 0x000000000042fc16 in aeMain (eventLoop=0x7ffff6c0b480) at ae.c:539 #11 0x000000000043d681 in main (argc=2, argv=0x7fffffffe588) at server.c:5259 (gdb) 可用单步进行观察,如下 (gdb) n 351 if (o != NULL && checkType(c,o,OBJ_STRING)) return; (gdb) n 352 if (getLongLongFromObjectOrReply(c,o,&value,NULL) != C_OK) return; (gdb) 354 oldvalue = value; (gdb) 355 if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) || (gdb) 356 (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) { (gdb) 360 value += incr; (gdb) 362 if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT && (gdb) 369 new = createStringObjectFromLongLongForValue(value); (gdb) 370 if (o) { (gdb) 371 dbOverwrite(c->db,c->argv[1],new); (gdb) 376 signalModifiedKey(c,c->db,c->argv[1]); (gdb) 377 notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id); (gdb) 378 server.dirty++; (gdb) 379 addReply(c,shared.colon); (gdb) 380 addReply(c,new); (gdb) 381 addReply(c,shared.crlf); (gdb) 382 } 最后用c命令执行服务端返回给客户端 (gdb) c Continuing. [Detaching after fork from child process 9977] 客户端得到返回结果如下 10.100.13.160:6379> incr test1 (integer) 4 (138.06s) 10.100.13.160:6379> 这里我们就完成了一个redis命令简单的调试