• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

输出nginx执行过程中函数调用关系

php 搞代码 4年前 (2022-01-23) 32次浏览 已收录 0个评论

添加源文件

首先在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 </span><span>void</span> enable_my_debug(<span>void</span>) __attribute__ (<div style="color:transparent">本文来源gaodai.ma#com搞##代!^码@网*</div><pre>搞gaodaima代码

(no_instrument_function));void disable_my_debug(void) __attribute__ ((no_instrument_function));int get_my_debug_flag(void) __attribute__ ((no_instrument_function));void set_my_debug_flag(int) __attribute__ ((no_instrument_function));void main_constructor(void) __attribute__ ((no_instrument_function, constructor));void main_destructor(void) __attribute__ ((no_instrument_function, destructor));void __cyg_profile_func_enter(void*, void*) __attribute__ ((no_instrument_function));void __cyg_profile_func_exit(void*, void*) __attribute__ ((no_instrument_function));#ifndef MY_DEBUG_MAINextern FILE *my_debug_fd;#elseFILE *my_debug_fd;#endif#endif

<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></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文件中‘\’表示不换行,但是我在’\’后面多加了空格,只要把空格删除就好了。

<script type=”text/javascript”> $(function () { $(‘pre.prettyprint code’).each(function () { var lines = $(this).text().split(‘\n’).length; var $numbering = $(‘

    ‘).addClass(‘pre-numbering’).hide(); $(this).addClass(‘has-numbering’).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('

  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

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


    搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
    转载请注明原文链接:输出nginx执行过程中函数调用关系

    喜欢 (0)
    [搞代码]
    分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址