Heim > Artikel > Backend-Entwicklung > Geben Sie die Funktionsaufrufbeziehung während der Nginx-Ausführung aus
添加源文件
首先在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>
<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>
以上就介绍了 输出nginx执行过程中函数调用关系,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。