# Debugging NGINX
Date: 2022-05-01


这篇文章来自nginx document  https://docs.nginx.com/nginx/admin-guide/monitoring/debugging/

nginx的故障排除和大多数程序一样， 可以通过gdb调试二进制文件， 增加debug日志，或者分析coredump文件方式解决。

#### **配置nginx**

nginx 商业版本从Release8开始已经提供nginx-debug版本，使用这个版本直接在配置文件中将日志设置成debug级别即可。

```
error_log  /var/log/nginx/error.log debug;
```

如果是开源版本， 需要增加**\--with-debug**标识重新编译， 步骤如下

```
$nginx -V 2>&1 | grep  arguments
$./congfigure --with-debug <other configure arguments>
$sudo make
$sudo make install
```

#####  **调试符号**

和大多数调试都需要增加调试符号，他可以提供除了内存地址以外的其他信息， 将可执行文件中的内存地址和如变量名称， 函数，类，数据结构，源码行数这些代码中的信息关联起来。

编译通过增加**\-g**可以包含调试符号。

```
$ ./configure --with-debug --with-cc-opt='-O0 -g'
```

#### **Debug日志**

当二进制支持debug日志后，还需要在配置文件中配置日志路径。日志可以存放到内存中， 标准输出中，或者指定的文件中。默认配置可以看到通过error\_log变量指定到文件中。

```
$ cat /etc/nginx/nginx.conf
$ error_log /var/log/nginx/error.log debug;
```

##### **内存方式**

配置

```
error_log memory:32m debug;
```

调试

```
$sudo gdb -p <pid>
```

将调试脚本拷贝到gdb中，按回车日志就会输出到 debug\_log.txt文件中

```
set $log = ngx_cycle->log
while $log->writer != ngx_log_memory_writer
    set $log = $log->next
end
set $buf = (ngx_log_memory_buf_t *) $log->wdata
dump binary memory debug_log.txt $buf->start $buf_end
```

按CTRL+D 退出gdb可以查看日志内容。

##### **调试指定IP**

可以在events段中指定要调试的IP地址或IP段。

```
events{
    debug_connection 192.168.1.1;
    debug_connection 192.18.10.0/24;
}
```

##### **调试指定VS**

```
error_log /path1/to/log debug;

http {
     server {
     error_log /path2/to/log debug;
     }
}
```

 

#### **CoreDumps**

可以通过操作系统，nginx两种方式进行配置

##### **通过操作系统方式**

- 取消core dump 文件限制；

```
$ mkdir /tmp/cores
$ sudo chown root:root /tmp/cores
$ sudo chmod 1777 /tmp/cores
$ ulimit -c unlimited
or
$ sudo sh -c "ulimit -c unlimited &&　exec su $LOGNAME"
```

- 指定文件名和目录

For CentOS 7.0, Debian 8.2, Ubuntu 14.04,

```
$ echo "/tmp/cores/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
$ sudo sysctl -w fs.suid_dumpable=2
$ sysctl -p
```

FreeBSD

```
$ sudo sysctl kern.sugid_coredump=1
$ sudo sysctl kern.corefile=/tmp/cores/%N.core.%P
```

##### **通过nginx方式**

- 配置文件指定目录及大小限制

```
working_directory /tmp/cores/;
worker_rlimit_core 500M;
```

- 设置目录权限

```
$ sudo chown root:root /tmp/cores
$ sudo chmod 1777 /tmp/cores
```

样例：

```
worker_processes   auto;
error_log          /var/log/nginx/error.log debug;
working_directory  /tmp/cores/;
worker_rlimit_core 500M;

events {
    ...
}

http {
    ...
}
```

获取coredump后可以通过bt执行查看crash时的堆栈信息定位问题。

```
$ sudo gdb <nginx_executable_path> <coredump_file_path>
(gdb) backtrace
```

 

#### **导出配置文件**

从运行的nginx master进程中导出配置文件， 需要可执行文件编译时使用--with-debug

```
set $cd = ngx_cycle->config_dump
set $nelts = $cd.nelts
set $elts = (ngx_conf_dump_t*)($cd.elts)
while ($nelts-- > 0) 
set $name = $elts[$nelts]->name.data
printf "Dumping %s to nginx_conf.txt\n", $name
append memory nginx_conf.txt \
      $elts[$nelts]->buffer.start $elts[$nelts]->buffer.end
end
```

使用场景:

- 判断配置文件加载是否正确
- 如果磁盘上的版本已意外删除或覆盖，则还原以前的配置

 

#### **参考及引用**

图片from [**動感感**](https://www.facebook.com/groups/474930279315210/user/100000367503761/?__cft__[0]=AZUUt4YdMTKG7IrPXow0jhUZM2ry1GLuPmTyrWOEhDe2L2pZWUB9efHXUO_h0f8Ib0FLY2TpQeVPN_BPysJMarDbCOMsRnvZWN_ZYn-udyFiMTALUBWJyiE-a0CZL89nnS0meZtk8ka3gz2BUFKTfULp6-FB7WnB58ko1vwBAMRog5gr2N9qpRRAIspS_b3ycfs&__tn__=-UC%2CP-R)

