nginx源码调试

编译Debug版本的nginx

下载nginx源码:http://nginx.org/en/download.html

在nginx官网上可以找到build的配置项,因为需要debug,所以需要使用--with-debug,并且由于nginx默认的gcc配置是-O,这种编译优化会导致vscode调试的时候无法定位具体的行号,可以使用--with-cc-opt="-O0"来关闭gcc的优化

执行如下命令:

./configure --prefix=/home/flight/environment/nginx/nginx-1.23.1-bin --with-cc-opt="-O0" --with-http_ssl_module --with-pcre --with-zlib=/home/flight/CLibrary/zlib-1.2.12 --with-debug
在成功生成Makefile之后就可以make && make install将nginx编译出来,现在就是debug版本的nginx了

使用vscode调试nginx

在生成带调试信息的nginx之后,就可以在vscode中打开nginx的源码配置相应的debug设置了
首先在vscode中生成launch.json,然后添加一个调试配置
image.png
生成以后,需要设置几个地方才能开启调试:

  1. 设置program的路径为刚才编译的nginx可执行文件的位置
  2. 设置args为["-g", "daemon off;"],这个设置是为了让nginx在前台运行,不然开启调试之后nginx会直接退出
  3. 设置setupCommands,添加{"text": "-gdb-set follow-fork-mode child"}配置,这个设置是因为nginx的请求处理是多进程的,每个新的http连接请求nginx都会新创建进程来处理,如果不设置这个选项,gdb是无法追踪子进程的调试的

最终的launch.json:

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        
        {
            "name": "调试nginx",
            "type": "cppdbg",
            "request": "launch",
            "program": "/home/flight/environment/nginx/nginx-1.23.1-bin/sbin/nginx",
            "args": ["-g", "daemon off;"],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description":  "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                },
                {"text": "-gdb-set follow-fork-mode child"}
            ],
        }
        
    ]
}

最后的效果

最后启动调试,在nginx_http_request.c文件中的ngx_http_process_request_line函数打断点,这里是负责http请求解析的模块,访问nginx的监听端口,即可触发断点
image.png