zoukankan      html  css  js  c++  java
  • Nginx代码调试——gdb工具

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

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

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

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

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

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

    daemon on;
    master_process on;
    worker_processes  1;

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

    1 gdb
    2 shell sbin/nginx
    3 shell pidof nginx

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

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

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

    1 (gdb) b ngx_process_events_and_timers
    2 Breakpoint 1 at 0x41b565: file src/event/ngx_event.c, line 195.
    3 (gdb) c
    4 Continuing.
    5 
    6 Breakpoint 1, ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:195
    7 195     {
    8 (gdb) 

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

    Breakpoint 1, ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:195
    195     {
    (gdb) n
    199         if (ngx_timer_resolution) {
    (gdb) n
    204             timer = ngx_event_find_timer();
    (gdb) n
    218         if (ngx_use_accept_mutex) {
    (gdb) n
    240         delta = ngx_current_msec;
    (gdb) n
    242         (void) ngx_process_events(cycle, timer, flags);
    (gdb) s
    ngx_epoll_process_events (cycle=0x9be050, timer=18446744073709551615, flags=1)
        at src/event/modules/ngx_epoll_module.c:702
    702     {
    (gdb) n
    717         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了。

     1 (gdb) b ngx_http_configprint_handler
     2 Breakpoint 2 at 0x4699a7: file /home/renwh/src/nginx-1.9.2/configprint//ngx_http_configprint_module.c, line 184.
     3 (gdb) c
     4 Continuing.
     5 
     6 Breakpoint 1, ngx_process_events_and_timers (cycle=0x9be050) at src/event/ngx_event.c:195
     7 195     {
     8 (gdb) s
     9 199         if (ngx_timer_resolution) {
    10 (gdb) n
    11 204             timer = ngx_event_find_timer();
    12 (gdb) n
    13 218         if (ngx_use_accept_mutex) {
    14 (gdb) n
    15 240         delta = ngx_current_msec;
    16 (gdb) c
    17 Continuing.
    18 
    19 Breakpoint 2, ngx_http_configprint_handler (r=0x9c8550)
    20     at /home/renwh/src/nginx-1.9.2/configprint//ngx_http_configprint_module.c:184
    21 184     {
    22 (gdb) n
    23 189             u_char ngx_my_string[1024] = {0};
    24 (gdb) n
    25 193             ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "ngx_http_configprint_handler is

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

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

  • 相关阅读:
    67. Add Binary
    66. Plus One
    64. Minimum Path Sum
    63. Unique Paths II
    How to skip all the wizard pages and go directly to the installation process?
    Inno Setup打包之先卸载再安装
    How to change the header background color of a QTableView
    Openstack object list 一次最多有一万个 object
    Openstack 的 Log 在 /var/log/syslog 里 【Ubuntu】
    Git 分支
  • 原文地址:https://www.cnblogs.com/paulweihan/p/4667216.html
Copyright © 2011-2022 走看看