输出nginx执行过程中函数调用关系
程序员文章站
2022-05-06 14:33:31
...
添加源文件
首先在src/core/目录下添加两个文件,分别是my_debug.h和my_debug.c。
#ifndef MY_DEBUG_LENKY_H#define MY_DEBUG_LENKY_H#include void enable_my_debug(void) __attribute__ ((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_MAIN
extern FILE *my_debug_fd;
#else
FILE *my_debug_fd;
#endif#endif
#include "my_debug.h"#define MY_DEBUG_FILE_PATH "/usr/local/nginx/sbin/mydebug.log"int _flag = 0;
#define open_my_debug_file() \
(my_debug_fd = fopen(MY_DEBUG_FILE_PATH, "a"))
#define close_my_debug_file() \do { \
if (NULL != my_debug_fd) { \
fclose(my_debug_fd); \
} \
}while (0)
#define my_debug_print(args, fmt...) \do { \
if (0 == _flag) { \
break; \
} \
if (NULL == my_debug_fd && NULL == open_my_debug_file()) { \
printf("Err: can not open output file.\n"); \
break; \
} \
fprintf(my_debug_fd, args, ##fmt); \
fflush(my_debug_fd); \
} while (0)
void enable_my_debug(void)
{
_flag = 1;
}
void disable_my_debug(void)
{
_flag = 0;
}
int get_my_debug_flag(void)
{
return _flag;
}
void set_my_debug_flag(int flag)
{
_flag = flag;
}
void main_constructor(void)
{
}
void main_destructor(void)
{
close_my_debug_file();
}
void __cyg_profile_func_enter(void *this, void *call)
{
my_debug_print("Enter\n%p\n%p\n", call, this);
}
void __cyg_profile_func_exit(void *this, void *call)
{
my_debug_print("Exit\n%p\n%p\n", call, this);
}
修改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中添加:
#include "my_debug.h"
- 在nginx.c中添加:
#define MY_DEBUG_MAIN 1
运行程序并用addr2line导出函数调用关系
运行程序:./objs/nginx,生成文件/usr/local/nginx/sbin/mydebug.log,路径是在my_debug.c中定义的。里面显示的只是函数的调用地址,可以写一个脚本addr2line.sh将地址转换为函数名。
#! /bin/sh
if [ $# != 3 ]; thenecho'Usage: addr2line.sh executefile addressfile functionfile'exitfi;
cat $2 | whileread line
doif [ "$line" = 'Enter' ]; thenread line1
read line2
# echo $line >> $3
addr2line -e$1-f$line1-s >> $3echo"--->" >> $3
addr2line -e$1-f$line2-s | sed 's/^/ /' >> $3echo >> $3elif [ "$line" = 'Exit' ]; thenread line1
read line2
addr2line -e$1-f$line2-s | sed 's/^/ /' >> $3echo" >> $3
addr2line -e$1-f$line1-s >> $3echo >> $3fi;
done
执行脚本:
./addr2line.sh ./objs/nginx /usr/local/nginx/sbin/mydebug.log myfun.log
就可以在mydebug.log中看到从nginx启动开始调用的各函数之间的关系。
截取一部分如下:
mainnginx.c:279--->
ngx_regex_initngx_regex.c:74ngx_regex_initngx_regex.c:74
---
推荐阅读