Home > Backend Development > PHP Tutorial > Output the function call relationship during nginx execution

Output the function call relationship during nginx execution

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Release: 2016-08-08 09:24:29
Original
1349 people have browsed it

添加源文件

首先在src/core/目录下添加两个文件,分别是my_debug.h和my_debug.c。

<code><span>#ifndef MY_DEBUG_LENKY_H</span><span>#define MY_DEBUG_LENKY_H</span><span>#include <stdio.h></span><span>void</span> enable_my_debug(<span>void</span>) __attribute__ ((no_instrument_function));
<span>void</span> disable_my_debug(<span>void</span>) __attribute__ ((no_instrument_function));
<span>int</span> get_my_debug_flag(<span>void</span>) __attribute__ ((no_instrument_function));
<span>void</span> set_my_debug_flag(<span>int</span>) __attribute__ ((no_instrument_function));
<span>void</span> main_constructor(<span>void</span>) __attribute__ ((no_instrument_function, constructor));
<span>void</span> main_destructor(<span>void</span>) __attribute__ ((no_instrument_function, destructor));
<span>void</span> __cyg_profile_func_enter(<span>void</span>*, <span>void</span>*) __attribute__ ((no_instrument_function));
<span>void</span> __cyg_profile_func_exit(<span>void</span>*, <span>void</span>*) __attribute__ ((no_instrument_function));


<span>#ifndef MY_DEBUG_MAIN</span>
extern<span> FILE </span>*my_debug_fd;
<span>#else</span>
FILE *my_debug_fd;
<span>#endif</span><span>#endif</span></code>
Copy after login
<code><span>#include "my_debug.h"</span><span>#<span>define</span> MY_DEBUG_FILE_PATH "/usr/local/nginx/sbin/mydebug.log"</span><span>int</span> _flag = <span>0</span>;

<span>#<span>define</span> open_my_debug_file() \</span>
    (my_debug_fd = fopen(MY_DEBUG_FILE_PATH, <span>"a"</span>))

<span>#<span>define</span> close_my_debug_file() \</span><span>do</span> { \
        <span>if</span> (NULL != my_debug_fd) { \
            fclose(my_debug_fd); \
        } \
    }<span>while</span> (<span>0</span>)

<span>#<span>define</span> my_debug_print(args, fmt...) \</span><span>do</span> { \
        <span>if</span> (<span>0</span> == _flag) { \
            <span>break</span>; \
        } \
        <span>if</span> (NULL == my_debug_fd && NULL == open_my_debug_file()) { \
            printf(<span>"Err: can not open output file.\n"</span>); \
            <span>break</span>; \
        } \
        fprintf(my_debug_fd, args, <span>##fmt); \</span>
        fflush(my_debug_fd); \
    } <span>while</span> (<span>0</span>)

<span>void</span> enable_my_debug(<span>void</span>)
{
    _flag = <span>1</span>;
}

<span>void</span> disable_my_debug(<span>void</span>)
{
    _flag = <span>0</span>;
}

<span>int</span> get_my_debug_flag(<span>void</span>)
{
    <span>return</span> _flag;
}

<span>void</span> set_my_debug_flag(<span>int</span> flag)
{
    _flag = flag;
}

<span>void</span> main_constructor(<span>void</span>)
{

}

<span>void</span> main_destructor(<span>void</span>)
{
    close_my_debug_file();
}

<span>void</span> __cyg_profile_func_enter(<span>void</span> *<span>this</span>, <span>void</span> *call)
{
    my_debug_print(<span>"Enter\n%p\n%p\n"</span>, call, <span>this</span>);
}

<span>void</span> __cyg_profile_func_exit(<span>void</span> *<span>this</span>, <span>void</span> *call)
{
    my_debug_print(<span>"Exit\n%p\n%p\n"</span>, call, <span>this</span>);
}</code>
Copy after login

修改Makefile

makefile有如下几个地方需要修改(加粗部分):
1. CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -finstrument-functions
2. CORE_DEPS = src/core/nginx.h \
src/core/my_debug.h \
3. HTTP_DEPS = src/http/ngx_http.h \
src/core/my_debug.h \
4. objs/nginx: objs/src/core/nginx.o \
objs/src/core/my_debug.o \
5. $(LINK) -o objs/nginx \
objs/src/core/my_debug.o \

将my_debug.h包含到源码中

需要修改如下两个地方:
1. 在ngx_core.h中添加:

<code><span>#include </span><span>"my_debug.h"</span></code>
Copy after login
  1. 在nginx.c中添加:
<code><span>#<span>define</span> MY_DEBUG_MAIN 1</span></code>
Copy after login

运行程序并用addr2line导出函数调用关系

运行程序:./objs/nginx,生成文件/usr/local/nginx/sbin/mydebug.log,路径是在my_debug.c中定义的。里面显示的只是函数的调用地址,可以写一个脚本addr2line.sh将地址转换为函数名。

<code><span>#! /bin/sh
</span><span>if</span> [ <span>$#</span> != <span>3</span> ]; <span>then</span><span>echo</span><span>'Usage: addr2line.sh executefile addressfile functionfile'</span><span>exit</span><span>fi</span>;

cat <span>$2</span> | <span>while</span><span>read</span> line
<span>do</span><span>if</span> [ <span>"<span>$line</span>"</span> = <span>'Enter'</span> ]; <span>then</span><span>read</span> line1
        <span>read</span> line2
<span>#       echo $line >> $3</span>
        addr2line <span>-e</span><span>$1</span><span>-f</span><span>$line1</span><span>-s</span> >> <span>$3</span><span>echo</span><span>"--->"</span> >> <span>$3</span>
        addr2line <span>-e</span><span>$1</span><span>-f</span><span>$line2</span><span>-s</span> | sed <span>'s/^/  /'</span> >> <span>$3</span><span>echo</span> >> <span>$3</span><span>elif</span> [ <span>"<span>$line</span>"</span> = <span>'Exit'</span> ]; <span>then</span><span>read</span> line1
        <span>read</span> line2
        addr2line <span>-e</span><span>$1</span><span>-f</span><span>$line2</span><span>-s</span> | sed <span>'s/^/  /'</span> >> <span>$3</span><span>echo</span><span>"<---"</span> >> <span>$3</span>
        addr2line <span>-e</span><span>$1</span><span>-f</span><span>$line1</span><span>-s</span> >> <span>$3</span><span>echo</span> >> <span>$3</span><span>fi</span>;
<span>done</span></span></code>
Copy after login

执行脚本:

<code>./addr2line.sh ./objs/nginx /usr/<span>local</span>/nginx/sbin/mydebug.<span>log</span> myfun.<span>log</span></code>
Copy after login

就可以在mydebug.log中看到从nginx启动开始调用的各函数之间的关系。
截取一部分如下:

<code><span>main</span><span>nginx</span><span>.c</span><span>:279</span><span>---</span>>
    <span>ngx_regex_init</span><span>ngx_regex</span><span>.c</span><span>:74</span><span>ngx_regex_init</span><span>ngx_regex</span><span>.c</span><span>:74</span>
<<span>---</span><span>main</span><span>nginx</span><span>.c</span><span>:279</span><span>main</span><span>nginx</span><span>.c</span><span>:313</span><span>---</span>>
    <span>ngx_os_init</span><span>ngx_posix_init</span><span>.c</span><span>:34</span><span>ngx_os_init</span><span>ngx_posix_init</span><span>.c</span><span>:38</span><span>---</span>>
    <span>ngx_os_specific_init</span><span>ngx_linux_init</span><span>.c</span><span>:35</span><span>ngx_os_specific_init</span><span>ngx_linux_init</span><span>.c</span><span>:35</span>
<<span>---</span><span>ngx_os_init</span><span>ngx_posix_init</span><span>.c</span><span>:38</span></code>
Copy after login

遇到的问题

1.我是在windows编辑shell脚本,因此文件格式是dos,可以在linux中用vi打开,在vi中用命令行查看:

<code><span>set</span> ff</code>
Copy after login

如果这样执行会出现错误:
/bin/sh^M: bad interpreter: No such file or directory
解决办法:
在vi中执行命令

<code><span>set</span> ff = unix</code>
Copy after login
  1. 在执行make命令时出现错误,
    no target ‘\’
    解决办法:
    在Makefile文件中‘\’表示不换行,但是我在’\’后面多加了空格,只要把空格删除就好了。

以上就介绍了 输出nginx执行过程中函数调用关系,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Issues
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template