Nginx代码调试——gdb工具
参考网上的资料,写了一个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工具的更多相关文章
- C++雾中风景番外篇3:GDB与Valgrind ,调试代码内存的工具
写 C++的同学想必有太多和内存打交道的血泪经验了,常常被 C++的内存问题搅的焦头烂额.(写 core 的经验了)有很多同学一见到 core 就两眼一抹黑,不知所措了.笔者 入"坑&quo ...
- GDB代码调试与使用
GDB代码调试与使用 Linux下GDB调试代码 源代码 编译生成执行文件 gcc -g test.c -o test 使用GDB调试 启动GDB:gdb test 从第一行列出源代码:list 直接 ...
- nginx源代码分析--GDB调试
利用gdb[i]调试nginx[ii]和利用gdb调试其他程序没有两样,只是nginx能够是daemon程序,也能够以多进程执行,因此利用gdb调试和寻常会有些许不一样. 当然,我们能够选择将ngin ...
- C/C++调试分析工具
一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...
- Linux下C语言的调试 - gdb
调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...
- 调试分析工具 (C/C++)
一.静态分析工具 cppcheck cppcheck主要用于对C/C++源代码进行分析检查的一个开源工具,可以用来检测未使用的变量.越界访问.内存泄漏等问题. 使用方法 cppcheck --enab ...
- 11个Visual Studio代码性能分析工具
软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...
- Android开发调试日志工具类[支持保存到SD卡]
直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...
- Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展
Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...
随机推荐
- Tomcat HTTP/1.1 Connector 参数整理
HTTP/1.1 Connector 概述 Coyote HTTP/1.1 Connector元素是一个支持HTTP/1.1协议的Connector组件.它使Catalina除了能够执行servlet ...
- SQLite Version3.3.6源代码文件结构
Version 3.3.6源代码文件结构 ——整理:hustcat 2009-2-19 文件名称 大小by ...
- NGUI 的使用教程与实例(入门)(1 )
NGUI教程:步骤1-Scene 1.创建一个新的场景(New Scene).2.选择并删除场景里的MainCamera.3.在NGUI菜单下选择Create a New UI,会打开UI创建向导. ...
- ANDROID_MARS学习笔记_S01原始版_005_RadioGroup\CheckBox\Toast
一.代码 1.xml(1)radio.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa ...
- ANDROID_MARS学习笔记_S01原始版_008_Looper\Bundle异步消息处理
一.流程 1.自定义Handler,重写handleMessage(Message msg),用msg得到bundle,从而得到传递过来的数据 2.开启android.os.HandlerThread ...
- Android 风格化的 Toggle Buttons
Android到默认UI比iOS到默认UI在美观程度上还是有一定到差距的,我们希望能够美化UI,并且替换掉系统默认的UI风格,使得程序在使用这些UI的时候都默认使用我们自定义到UI.本文以Toggle ...
- 同一客户代码下一个CPN对应多个FG会出现CPN描述一样的问题
Q&A : D2E01客户下已经存在CPN: TP1062/A 对应FG: P5M2812512AFHHF0 直接在客户代码下无法新建,只能在交叉信息新建CPN: TP1062/A, 但无法修 ...
- POJ_3258_River_Hopscotch_[NOIP2015]_(二分,最大化最小值)
描述 http://poj.org/problem?id=3258 给出起点和终点之间的距离L,中间有n个石子,给出第i个石子与起点之间的距离d[i],现在要去掉m个石子(不包括起终点),求距离最近的 ...
- eight - zoj 1217 poj 1077
学习了多位大牛的方法,看看到底能把时耗降到多少? A* // zojfulltest: 30000ms # include <stdio.h> # include <ctype.h& ...
- c#调用带有安全认证的java webservice
最近使用c#调用另外一个同事写的java webservice耽误了很多时间,网上资料不太完整,走了很多弯路,希望对大家有帮助. 基本思路是1.拼装soap使用http post ,主要将验证身份信息 ...