《Nginx官方文档》用DTrace pid提供程序调试nginx

用DTrace pid提供程序调试nginx

本文假设读者对nginx内部和 DTrace 有一般的了解。

虽然使用 –with-debug 选项构建的nginx 已经提供了大量关于请求处理的信息,但是有时候更有必要更详细地跟踪代码路径的特定部分,同时省略其余的调试输出。DTrace pid提供程序(在Solaris,MacOS上可用)是浏览用户程序内部的有用工具,因为它不需要任何代码更改,并且可以帮助您完成任务。跟踪和打印nginx函数调用的简单DTrace脚本可能如下所示:

#pragma D option flowindent

pid$target:nginx::entry {
}

pid$target:nginx::return {
}

尽管如此,功能调用跟踪的DTrace功能仅提供有限的有用信息。功能参数的实时检查通常更有趣,但也更复杂一些。以下示例旨在帮助读者更熟悉DTrace以及使用DTrace分析nginx行为的过程。

使用DTrace与nginx的常见方案之一是:附加到nginx工作进程以记录请求行和请求开始时间。附加的相应函数是 ngx_http_process_request(),而有争议的参数是指向ngx_http_request_t结构的指针。这种请求记录的DTrace脚本可以简单到:

pid$target::*ngx_http_process_request:entry
{
    this->request = (ngx_http_request_t *)copyin(arg0, sizeof(ngx_http_request_t));
    this->request_line = stringof(copyin((uintptr_t)this->request->request_line.data,
                                         this->request->request_line.len));
    printf("request line = %s/n", this->request_line);
    printf("request start sec = %d/n", this->request->start_sec);
}

应该注意的是,在上面的例子中,DTrace需要一些关于ngx_http_process_request结构的知识。不幸的是,可以在DTrace脚本中使用特定的#include指令,然后将其传递给C预处理器(带有-C标志),但这并不真正有效。由于很多交叉依赖关系,几乎所有的nginx头文件都必须包含在内。反过来,根据configure脚本设置,nginx头将包括PCRE,OpenSSL和各种系统头文件。在理论上,与特定的nginx构建相关的所有头文件可能都包含在DTrace脚本预处理和编译中,实际上DTrace脚本最有可能由于某些头文件中的未知语法而无法编译。

上述问题可以通过在DTrace脚本中仅包含相关且必要的结构和类型定义来解决。DTrace必须知道结构,类型和字段偏移的大小。因此,通过手动优化用于DTrace的结构定义,可以进一步降低依赖性。

让我们使用上面的DTrace脚本示例,看看它需要正确的结构定义。

首先,由configure生成的objs/ngx_auto_config.h文件应该被包括,因为它定义了一些影响各种各样的常量 #ifdef’s。在此之后,像ngx_str_t,ngx_table_elt_t, ngx_uint_t等一样的一些基本的类型和定义应放在DTrace脚本的开始位置。这些定义是紧凑的,常用的,不太可能经常改变。

在ngx_http_process_request_t结构中包含了很多指向其他结构的指针。因为这些指针与这个脚本无关,而且因为它们具有相同的大小,所以可以用void指针替换它们。而不是更改定义,最好添加适当的typedefs,但是:

typedef ngx_http_upstream_t     void;
typedef ngx_http_request_body_t void;

最后但并非最不重要的是添加两个成员结构(ngx_http_headers_in_t, ngx_http_headers_out_t)的定义,回调函数的声明和常量的定义。

最后的DTrace脚本可以从 这里 下载 。

以下示例显示运行此脚本的输出:

# dtrace -C -I ./objs -s trace_process_request.d -p 4848
dtrace: script 'trace_process_request.d' matched 1 probe
CPU     ID                    FUNCTION:NAME
  1      4 .XAbmO.ngx_http_process_request:entry request line = GET / HTTP/1.1
request start sec = 1349162898

  0      4 .XAbmO.ngx_http_process_request:entry request line = GET /en/docs/nginx_dtrace_pid_provider.html HTTP/1.1
request start sec = 1349162899

使用类似的技术,读者应该能够跟踪其他nginx函数调用。

也可以看看

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/99540.html

(0)
上一篇 2021年8月21日
下一篇 2021年8月21日

相关推荐

发表回复

登录后才能评论