输出nginx执行过程中函数调用关系
添加源文件
首先在src/core/目录下添加两个文件,分别是my_debug.h和my_debug.c。
#ifndef MY_DEBUG_LENKY_H
#define MY_DEBUG_LENKY_H#include <stdio.h>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"
- 1
- 在nginx.c中添加:
#define MY_DEBUG_MAIN 1
- 1
在main函数添加 enable_my_debug();
运行程序并用addr2line导出函数调用关系
运行程序:./objs/nginx,生成文件/usr/local/nginx/sbin/mydebug.log,路径是在my_debug.c中定义的。里面显示的只是函数的调用地址,可以写一个脚本addr2line.sh将地址转换为函数名。
#! /bin/shif [ $# != 3 ]; thenecho 'Usage: addr2line.sh executefile addressfile functionfile'exit
fi;cat $2 | while read line
doif [ "$line" = 'Enter' ]; thenread line1read line2
# echo $line >> $3addr2line -e $1 -f $line1 -s >> $3echo "--->" >> $3addr2line -e $1 -f $line2 -s | sed 's/^/ /' >> $3echo >> $3elif [ "$line" = 'Exit' ]; thenread line1read line2addr2line -e $1 -f $line2 -s | sed 's/^/ /' >> $3echo "<---" >> $3addr2line -e $1 -f $line1 -s >> $3echo >> $3fi;
done
- 1
执行脚本:
./addr2line.sh ./objs/nginx /usr/local/nginx/sbin/mydebug.log myfun.log
- 1
就可以在mydebug.log中看到从nginx启动开始调用的各函数之间的关系。
截取一部分如下:
main
nginx.c:279
--->ngx_regex_initngx_regex.c:74ngx_regex_initngx_regex.c:74
<---
main
nginx.c:279main
nginx.c:313
--->ngx_os_initngx_posix_init.c:34ngx_os_init
ngx_posix_init.c:38
--->ngx_os_specific_initngx_linux_init.c:35ngx_os_specific_initngx_linux_init.c:35
<---
ngx_os_init
ngx_posix_init.c:38
遇到的问题
1.我是在windows编辑shell脚本,因此文件格式是dos,可以在linux中用vi打开,在vi中用命令行查看:
set ff
- 1
如果这样执行会出现错误:
/bin/sh^M: bad interpreter: No such file or directory
解决办法:
在vi中执行命令
set ff = unix
- 1
- 在执行make命令时出现错误,
no target ‘\’
解决办法:
在Makefile文件中‘\’表示不换行,但是我在’\’后面多加了空格,只要把空格删除就好了
输出nginx执行过程中函数调用关系相关推荐
- 一个进程在执行过程中可以被中断事件打断_Linux操作系统:中断类型和中断的作用...
1.中断的概念 中断对于操作系统非常重要,它就好像机器中的齿轮,驱动各部件的动作.所以,许多人称操作系统是由"中断驱动"的. 所谓中断是指CPU对系统发生的某个事件做出的一种反应, ...
- 项目计划执行过程中,如何分析进度偏差?
在项目计划的执行过程中,通过对执行过程的跟踪检查,找出实际进度与计划进度之间的偏差,分析偏差原因并找出解决办法. 如果无法完成原来的目标计划,就需要对原来的计划进行更新. 项目进度更新后我们可以分析进 ...
- 关于 go run 命令执行过程中的“坑坑点点”
问题 解决 结尾 问题 在使用 Golang 编写程序的时候,经常会遇到单文件编译运行的场景,当我们使用一般的编译语句去编译的时候往往会报错,到底是怎么回事儿呢?接下我们结合具体的例子分析一下. 解决 ...
- linux脚本执行过程中被挂起,Linux学习笔记(八)——脚本执行的过程控制
一.脚本执行过程中的控制 之前的内容中,运行编写好的脚本时都是在命令行上直接确定运行的,并且运行的脚本是实时的,这并不是脚本唯一的运行方式,下面的内容是脚本的其他运行方式.例如在Linux系统中如何控 ...
- Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...
在维护一个非常旧的项目时,由于该项目版本已经非常老了,而且在客户现场运行的非常稳定,更要命的是本人目前没有找到该项目的代码,为了处理一个新的需求而且还不能修改程序代码,于是决定从数据库入手,毕竟该项目 ...
- 在动作观察,运动想象和站立和坐姿执行过程中解码脑电节律
事件相关去同步化与同步化(ERD/S)和运动相关皮质电位(MRCP)在下肢康复的脑机接口(BCI)中,特别是在站立和坐姿中,起着重要的作用.然而,人们对站立和坐着的大脑皮层活动的差异知之甚少,尤其是大 ...
- java 方法执行结束局部变量释放_JAVA-方法在执行过程中,JVM的内存分配和变化情况,栈(stack)的情况浅析...
方法在执行过程中,在JVM中的内存是如何分配的?内存是如何变化的? 一.方法只定义不调用,是不会被执行的,并且在JVM中也不会给该方法分配"运行所属"的内存空间.只有在调用这个方法 ...
- python 利用pyinstaller 编译.exe文件过程中编写完的.exe文件执行过程中闪退
问题描述: python 利用pyinstaller 编译.exe文件过程中编写完的.exe文件执行过程中闪退,并提示no module named 'pyproj.datadir' 解决方法: 闪退 ...
- 对下图所示的连通网络G,用克鲁斯卡尔(Kruskal)算法求G的最小生成树T,请写出在算法执行过程中,依次加入T的边集TE中的边。说明该算法的基本思想及贪心策略,并简要分析算法的时间复杂度
对下图所示的连通网络G,用克鲁斯卡尔(Kruskal)算法求G的最小生成树T,请写出在算法执行过程中,依次加入T的边集TE中的 边.说明该算法的基本思想及贪心策略,并简要分析算法的时间复杂度
最新文章
- Python爬虫-Scrapy-CrawlSpider与ItemLoader
- signature=0e42fe6b348b65f88748ba8ecefece12,Low power BIST
- Java Pattern类的用法详解(正则表达式)
- 如何在不同的浏览器中设置Selenium网格以并行执行
- 华为发布全容器化 5G 核心网;余承东评小米 MIX Aphla 手机无实用价值;PHP 新版本更新 | 极客头条...
- 程序开发——结对编程
- 应届生软件测试面经_应届生软件测试面试自我介绍
- PSFTP工具传输文件的命令使用方法
- 番茄社区门店系统新增跑腿和空码功能
- 银行卡卡号识别(照片)python
- arcgis标注牵引线_ArcEngine设置有牵引线的标注
- 200行代码构建一个区块链
- 钉钉小程序从搭建到引入地三方库到发布---企业内小程序
- 成功解决3dmax打开或导入模型文件的时候,出现文件打开失败
- 大文件传输软件的优势你了解吗?
- matlab怎么产生一个随机数,matlab怎么产生随机数
- c语言注释两种,C语言有几种注释方式
- 摄像机,光源和阴影 -----OGRE 3D 1.7 Beginner‘s Guide中文版 第四章
- 圣诞节购物季:我们可以花加密货币购买礼物
- 网络工程师的敲门砖,2022最新HCIA-Datacom题库H12-811首发分享
热门文章
- 微信大更新,可以“远程控制”他人微信了!
- 聊一聊:我退钱了!你呢?
- 18香警告:一个女生勿近的邪恶开源项目...
- 于其炒股,不如......
- 为什么Kafka中的分区数只能增加不能减少?
- apply筛选 pandas_更快的pandas.apply搜索方法
- Oracle分区表详解 .
- error: ‘__declspec‘ attributes are not enabled; use ‘-fdeclspec‘ or ‘-fms-extensions‘ to enabl
- python meshgrid()理解
- oneshot单样本学习笔记