参考网上的资料,写了一个configprint模块,其功能为打印输出location配置内容,并计数访问次数。

代码链接如下:https://github.com/PaulWeiHan/nginx_module_development

程序的编写到运行总不是一帆风顺的,编译通过,运行不过的情况是最让我抓狂的。

这里记录一下gdb调试过程。供大家参考:

(这里没有gdb命令说明,请自行百度)

我使用的是nginx的默认模式即:

daemon on;
master_process on;
worker_processes ;

我们知道。nginx默认执行的时候,是以daemon模式运行在后台,并且,由master进程fork出多个work子进程来监听端口的。切到nginx目录,执行下面命令:

 gdb
shell sbin/nginx
shell pidof nginx

这样,我们就可以得到nginx的pid,一般会是两个,由于worker子进程是fork master得来的,所以自然worker进程的pid较大。利用gdb的attach和detach命令追踪worker子进程。

(gdb) shell pidof nginx

(gdb) attach
Attaching to process
Reading symbols from /home/renwh/nginx/sbin/nginx...done.
Reading symbols from /lib64/libpthread.so....(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.
Reading symbols from /lib64/libcrypt.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libcrypt.so.
Reading symbols from /lib64/libpcre.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libpcre.so.
Reading symbols from /lib64/libz.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libz.so.
Reading symbols from /lib64/libc.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.
Reading symbols from /lib64/ld-linux-x86-.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-.so.
Reading symbols from /lib64/libfreebl3.so...(no debugging symbols found)...done.
Loaded symbols for /lib64/libfreebl3.so
Reading symbols from /lib64/libdl.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.
Reading symbols from /lib64/libnss_files.so....(no debugging symbols found)...done.
Loaded symbols for /lib64/libnss_files.so.
0x00000031684e8fb3 in __epoll_wait_nocancel () from /lib64/libc.so.
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64 nss-softokn-freebl-3.14.-.el6.x86_64 pcre-7.8-.el6.x86_64 zlib-1.2.-.el6.x86_64
(gdb)

子进程即worker进程在运行后会停留在epoll_wait处等待相应的事件发生,而这个函数调用被封装在ngx_process_events_and_timers 中。于是我们在这个函数出设置一个断点:b ngx_process_events_and_timers.然后采用命令c,使得nginx一直运行,直到遇到第一个断点:

 (gdb) b ngx_process_events_and_timers
Breakpoint at 0x41b565: file src/event/ngx_event.c, line .
(gdb) c
Continuing. Breakpoint , ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:
{
(gdb)

进去之后,一直用n向下运行,直到找到ngx_process_events,然后用s追踪进该函数,一直n,直到运行到epoll_wait,发现,停在了这里,我们知道work子进程在等待事件了。

Breakpoint , ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:
{
(gdb) n
if (ngx_timer_resolution) {
(gdb) n
timer = ngx_event_find_timer();
(gdb) n
if (ngx_use_accept_mutex) {
(gdb) n
delta = ngx_current_msec;
(gdb) n
(void) ngx_process_events(cycle, timer, flags);
(gdb) s
ngx_epoll_process_events (cycle=0x9be050, timer=, flags=)
at src/event/modules/ngx_epoll_module.c:
{
(gdb) n
events = epoll_wait(ep, event_list, (int) nevents, timer);
(gdb) n

这时候,你只需要打开一个浏览器,访问你配置好的nginx模块的url,然后你就会发现gdb可以向下运行了。这时候,你需要在你自己的handler函数处设置断点,然后c,你会发现,又一次调用了ngx_process_events_and_timers函数,s进入函数,继续c运行,然后gdb会停在你自己的handler函数入口,这里是:ngx_http_configprint_handler。s追踪进去,你就可以单步执行你自己写的handler函数,进行debug了。

 (gdb) b ngx_http_configprint_handler
Breakpoint at 0x4699a7: file /home/renwh/src/nginx-1.9./configprint//ngx_http_configprint_module.c, line 184.
(gdb) c
Continuing. Breakpoint , ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:
{
(gdb) s
if (ngx_timer_resolution) {
(gdb) n
timer = ngx_event_find_timer();
(gdb) n
if (ngx_use_accept_mutex) {
(gdb) n
delta = ngx_current_msec;
(gdb) c
Continuing. Breakpoint , ngx_http_configprint_handler (r=0x9c8550)
at /home/renwh/src/nginx-1.9./configprint//ngx_http_configprint_module.c:184
{
(gdb) n
u_char ngx_my_string[] = {};
(gdb) n
ngx_log_error(NGX_LOG_EMERG, r->connection->log, , "ngx_http_configprint_handler is

gdb不光可以帮你debug,还可以帮你理解整个nginx的运行过程。你可以尝试在自己的handler挂载函数,loc_conf创建函数等地方添加断点,来查看整个模块的调用过程。

个人理解,欢迎讨论。联系方式:rwhsysu@163.com

Nginx代码调试——gdb工具的更多相关文章

  1. C++雾中风景番外篇3:GDB与Valgrind ,调试代码内存的工具

    写 C++的同学想必有太多和内存打交道的血泪经验了,常常被 C++的内存问题搅的焦头烂额.(写 core 的经验了)有很多同学一见到 core 就两眼一抹黑,不知所措了.笔者 入"坑&quo ...

  2. GDB代码调试与使用

    GDB代码调试与使用 Linux下GDB调试代码 源代码 编译生成执行文件 gcc -g test.c -o test 使用GDB调试 启动GDB:gdb test 从第一行列出源代码:list 直接 ...

  3. nginx源代码分析--GDB调试

    利用gdb[i]调试nginx[ii]和利用gdb调试其他程序没有两样,只是nginx能够是daemon程序,也能够以多进程执行,因此利用gdb调试和寻常会有些许不一样. 当然,我们能够选择将ngin ...

  4. C/C++调试分析工具

    一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...

  5. Linux下C语言的调试 - gdb

    调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...

  6. 调试分析工具 (C/C++)

    一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...

  7. 11个Visual Studio代码性能分析工具

    软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...

  8. Android开发调试日志工具类[支持保存到SD卡]

    直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...

  9. Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展

    Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...

随机推荐

  1. Hibernate 一对多自身双向关联关系 用于类别表的实现

    分类:一对多自身双向关联关系 Java持久化类: package com.hyy.hibernate.one_to_many.domain; import java.util.HashSet; imp ...

  2. 严重: The web application [] registered the JDBC driver 错误

    近日发现启动tomcat的时候报如下警告: -- :: org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc 严重: The ...

  3. nginx -t "nginx: [warn] only the last index in "index" directive should be absolute in 6 "的问题解决

    修改完nginx的配置文件之后,执行nginx -t命令提示"nginx: [warn] only the last index in "index" directive ...

  4. 发现一个好的开源项目:lomoX(挑着看,每天看一点,看一年就ok了)——用Webkit开发桌面软件,炫

    http://www.oschina.net/p/lomox https://github.com/caidongyun/lomox 用Web技术做桌面客户端.虽然仍然免不了要分发客户端,但好处是,界 ...

  5. java代码转换为c# 工具

    Demo Java to C# Converter.exe 已下载到 F:\SoftWare-new\java\Java_to_CSharp_Converter.rar

  6. str.match(regex)与regex.exec(str)对比解析,从此不再晕

    match属于字符串的方法,exec属于正则表达式的方法.其中regex是否有g标志的区别经常搞不清,所以测试记录下. 1.str.match(regex) regex中无g标志 返回一个数组,arr ...

  7. 【HDOJ】1857 Word Puzzle

    trie树.以puzzle做trie树内存不够,从puzzle中直接找串应该会TLE.其实可以将查询组成trie树,离线做.扫描puzzle时注意仅三个方向即可. /* 1857 */ #includ ...

  8. poj2029Get Many Persimmon Trees(最大矩阵和)

    链接 类似最大矩阵 sum存下 枚举最大就是 #include <iostream> #include<cstdio> #include<cstring> #inc ...

  9. poj1160Post Office(DP)

    http://poj.org/problem?id=1160 算水过的吧 四重循环没优化 CZ说爆可过 就爆了 dp[i][j] = min(dp[i][j],dp[i-1][g]-s) 第i个点建在 ...

  10. bzoj1801

    题目就是每行每列最多放两个炮的意思: 首先不难想到状态压缩dp,但是当n,m<=100的时候显然会跪掉: 考虑每行最多就2个点,状压dp浪费了大量的空间 由于每行最多两个点,我们可以直接用f[i ...