nginx実行時の関数呼び出し関係を出力する

WBOY
リリース: 2016-08-08 09:24:29
オリジナル
1323 人が閲覧しました

添加源文件

首先在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>
ログイン後にコピー
<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>
ログイン後にコピー

修改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>
ログイン後にコピー
  1. 在nginx.c中添加:
<code><span>#<span>define</span> MY_DEBUG_MAIN 1</span></code>
ログイン後にコピー

运行程序并用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>
ログイン後にコピー

执行脚本:

<code>./addr2line.sh ./objs/nginx /usr/<span>local</span>/nginx/sbin/mydebug.<span>log</span> myfun.<span>log</span></code>
ログイン後にコピー

就可以在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>
ログイン後にコピー

遇到的问题

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

<code><span>set</span> ff</code>
ログイン後にコピー

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

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

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート