> For the complete documentation index, see [llms.txt](https://docshome.gitbook.io/nginx-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docshome.gitbook.io/nginx-docs/how-to/shi-yong-dtracepid-ti-gong-cheng-xu-tiao-shi-nginx.md).

# 使用 DTrace pid 提供程序调试 nginx

本文假设读者对 nginx 内部原理和 [DTrace](http://nginx.org/en/docs/nginx_dtrace_pid_provider.html#see_also) 有了一定的了解。

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

```d
#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 脚本实现这种请求日志记录可以简单到：

```d
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 和各种系统头文件。理论上，在 DTrace 脚本预处理和编译时，与特定的 nginx 构建相关的所有头文件都有可能被包含进来，实际上 DTrace 脚本很有可能由于某些头文件中的未知语法而造成无法编译。

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

让我们使用上面的 DTrace 脚本示例，看看它需要哪些结构定义才能正常地工作。

首先应该包含由 configure 生成的 `objs/ngx_auto_config.h` 文件，因为它定义了一些影响各个方面的 `＃ifdef` 常量。之后，一些基本类型和定义（如 `ngx_str_t`，`ngx_table_elt_t`，`ngx_uint_t` 等）应放在 DTrace 脚本的开头。这些定义经常被使用但不太可能经常改变的。

那里有一个包含许多指向其他结构的指针的 ngx\_http\_process\_request\_t 结构。因为这些指针与这个脚本无关，而且因为它们具有相同的大小，所以可以用 void 指针来替换它们。但最好添加合适的 typedef，而不是更改定义：

```d
typedef ngx_http_upstream_t     void;
typedef ngx_http_request_body_t void;
```

最后但同样重要的是，需要添加两个成员结构的定义（`ngx_http_headers_in_t`，`ngx_http_headers_out_t`）、回调函数声明和常量定义。

最后，DTrace 脚本可以从 [这里](http://nginx.org/download/trace_process_request.d) 下载。

以下示例是运行此脚本的输出：

```
# 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 函数调用。

## 相关阅读

* [Solaris 动态跟踪指南](http://docs.oracle.com/cd/E19253-01/817-6223/index.html)
* [DTrace pid 提供程序介绍](http://dtrace.org/blogs/brendan/2011/02/09/dtrace-pid-provider/)

## 原文档

<http://nginx.org/en/docs/nginx_dtrace_pid_provider.html>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docshome.gitbook.io/nginx-docs/how-to/shi-yong-dtracepid-ti-gong-cheng-xu-tiao-shi-nginx.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
