添加源文件
首先在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></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教程有兴趣的朋友有所帮助。
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号