记一次nginx module 调试

参考了https://blog.csdn.net/xiajun07061225/article/details/9383883

 

先进入nginx工作目录 /usr/local/nginx/sbin/

使用gdb -q -tui(q选项是以安静模式启动,不显示GDB版本等信息。tui选项可以显示代码界面)

 

然后在gdb中启动nginx  shell ./nginx

启动之后,可以查看当前nginx中的进程号:shell pidof nginx

也可以使用ps -ef|grep nginx 查看(在另一个窗口中)

 

可以使用attach命令跟踪子进程 attach <port>

可以发现子进程即worker进程在运行后会停留在epoll_wait处等待相应的事件发生

 

测试之前的hello module

首先给hello module中的ngx_http_hello_handler函数打上断点,也就是这种handler模块的处理函数,这种函数是真正用来处理请求并发回响应包体给客户端的。使用 b ngx_http_hello_handler打断点。(使用i b可以查询断点)然后用命令c让nginx一直运行,直到遇到第一个断点。(使用delete breakpoint b_num删除断点,如delete breakpoint 1)

 

使用bt显示当前函数的调用栈,使用frame n(eg:frame 1)可进入具体某一帧

 

然后可以在另一个终端中输入 wget 100.100.60.199/hello或者使用postman 如图

 

 

 

send即可,然后就可以看到代码界面了。

 

使用n命令向下运行,主要是跟踪最后调用的输出函数return ngx_http_output_filter,运行到这一句时使用s命令进入该函数

 

继续执行到rc=ngx…这句,再次使用s命令进入该函数

 

发现进入的是这个ngx_http_range_body_filter函数,继续执行发现进入了ctx==null这句,使用p ctx可以查看ctx的值,是0x0,进入ngx_http_next_body_filter函数,发现进入了ngx_http_copy_filter函数

 

 

 

最后运行到rc=…时,进入ngx_output_chain函数,

 

 

继续运行,发现进入了in->next==NULL分支,可以使用p in->next查看,然后进入output_filter,发现进入了ngx_http_trailers_filter函数

 

这里就不一一截图了,就是很多filter函数在把处理往下推,大致进程如下

 

 

上方为调用(进入)的函数,下方为进入时的条件,可以看到,最后请求的处理被丢给了ngx_http_write_filter函数,该函数在运行到

 

时,使用s命令进入,发现进入了ngx_linux_sendfile_chain函数,该函数调用了ngx_output_chain_to_iovec函数,大致的流程如下

 

 

最后在ngx_writev函数中调用了writev函数,运行到这一步时postman中收到了输出。

 

writev函数介绍,参照http://blog.lucode.net/linux/talk-about-the-problem-of-writev.html

writev函数:是POSIX提供的一个比write函数更加高级的writev,在很多场景下,它相对于write有一定的优势。大体而言,write面向的是连续内存块,writev面向的是分散的数据块,两个函数的最终结果都是将内容写入连续的空间。分散的数据块,显然与nginx链式输出的规则符合。

 

函数原型:writev(int fd, struct iovect* iov, int iovcnt);

iov_base就是每个pair的基址,iov_len则是长度,不用包含“0”。

 

ngx_iovec_t结构体的定义

typedef struct {

    struct iovec  *iovs;

    ngx_uint_t     count;      //当前所使用的iovs的个数

    size_t         size;       //当前存放的总的字节数

    ngx_uint_t     nalloc;     //总的iovs个数

} ngx_iovec_t;

 

iovec结构体

#include <sys/uio.h>

 

struct iovec {

ptr_t iov_base; /* Starting address */

size_t iov_len; /* Length in bytes */

};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值