Mac/Linux 下使用 vscode 调试 redis 源码(超方便)

2023年 8月 15日 69.3k 0

环境准备

用 vscode 进行调试需要配合 debug 工具使用,一般系统会自带这些工具,如果你的系统下没有对应的可执行文件,请自行从网上下载并能够正常执行。

  • Linux:gdb
  • MacOS(包含 M 系列芯片): lldb

除了 debug 工具外,还要确保能够正常编译出 redis 的可执行文件,具体可以看官方指南。

编译 redis

我们可以直接在源码根目录下执行 make 来编译 redis 可执行文件,但默认情况下,redis 编译会开启 -O2 优化,这种情况下很难使用 debug 工具进行调试。我们可以将编译命令换成 make noopt

$ make noopt

如果在 Linux 上出现 jemalloc/jemalloc.h: No such file or directory 相关错误可以加上参数:

make noopt MALLOC=libc

执行完成后,在 src 目录下会生成 redis-serverredis-cliredis-sentinel 等可执行文件,即对应 redis 服务端、客户端和哨兵。

vscode 配置

Run and Debug 面板创建一个 launch.json 文件,不同的操作系统对应不同的配置。

image.png

小技巧:在 configurations 下输入 gdblldb 可以快速生成启动模板,一般情况下选择 Launch 就行。

image.png

Linux

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch", // 名字随便取
            "type": "cppdbg",
            "request": "launch",
            // 可执行程序位置,这里我们启动 redis 服务端
            "program": "${workspaceFolder}/src/redis-server",
            // 程序参数 
            "args": [ 
                // 例如:使用配置文件启动 
                // "/path/to/your/redis.conf" 
            ],
            "stopAtEntry": false,
            // 可执行程序的工作目录,也可以使用绝对路径
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

MacOS

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb Launch)", // 名字随便取
            "type": "cppdbg",
            "request": "launch",
            // 可执行程序位置,这里我们启动 redis 服务端
            "program": "${workspaceFolder}/src/redis-server", 
            // 程序参数
            "args": [ 
                // 例如:使用配置文件启动
                // "/path/to/your/redis.conf"
            ],
            "stopAtEntry": false,
            // 可执行程序的工作目录,也可以使用绝对路径
            "cwd": "${fileDirname}", 
            "environment": [],
            "externalConsole": false,
            "MIMode": "lldb",
            "setupCommands": [
                {
                  "description": "Enable pretty-printing",
                  "text": "-enable-pretty-printing",
                  "ignoreFailures": true
                }
            ]
        }
    ]
}

配置完成后,我们就可以在程序中打断点进行调试了。例如在源码 src/server.c 的入口函数中打上断点,再使用 vscode 启动程序,就能够成功进入断点了:

image.png

最后贴一下 AI 总结的调试器底层原理:

GDB 和 LLDB 这类调试器可以调试二进制文件的底层原理主要有以下几点:

  • 程序中断机制 - 调试器可以设置断点,当程序执行到断点时会触发中断,转而执行调试器的代码。这通常是通过修改可执行文件的机器代码实现的。
  • 寄存器和内存读取 - 调试器可以读取 cpu 寄存器和内存的值,来检查程序的运行状态。这通过调试器和 cpu 之间的接口实现。
  • 反汇编 - 调试器可以将二进制代码反汇编成汇编语言,以便于理解程序在做什么。
  • 函数调用栈 - 调试器可以显示和操作函数调用栈,用于跟踪程序的执行流程。
  • 符号表 - 调试器使用可执行文件中的调试符号表信息,将机器代码映射到源代码,以便于开发者调试。
  • 线程控制 - 调试器可以控制不同线程的执行,用于多线程程序调试。
  • 观察点 - 除了断点外,调试器还支持在读取/写入内存时等触发观察点。
  • 总之,调试器直接作用于程序的机器代码,并通过不同的接口查看和控制程序的运行,来实现调试的功能。良好的二进制接口是调试器可以顺利工作的基础。

    -- Claude

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论