当前位置: 首页 > news >正文

上海长宁网站建设网页版qq游戏大厅

上海长宁网站建设,网页版qq游戏大厅,wordpress页脚设置,WordPress高级微信机器人前面介绍的mtrace也好#xff0c;bcc也罢#xff0c;其实都是hook技术的一种实现#xff0c;但是mtrace本身使用场景上有局限#xff0c;而bcc环境依赖则十分复杂。因此#xff0c;这些调试手段只适用于开发环境用来调试#xff0c;对于生产环境#xff0c;均不是一个非…前面介绍的mtrace也好bcc也罢其实都是hook技术的一种实现但是mtrace本身使用场景上有局限而bcc环境依赖则十分复杂。因此这些调试手段只适用于开发环境用来调试对于生产环境均不是一个非常好的方法。 但其实所谓的hook技术本身并不复杂说白了就是重载malloc/free函数让代码在调用malloc函数时先调用我们自己定义的malloc由自定义的malloc完成一些前置统计工作后再去调用系统的malloc从而完成一些内存的统计分析。明白了这一点其实我们可以轻而易举地自己实现一套hook机制嵌入到代码中这样带来的好处显而易见 不依赖其他检测工具可以非常方便地在开发环境甚至在线上进行调试可以在代码里通过开关的方式控制是否检测内存泄漏如线上默认关闭如果怀疑出现内存泄漏则将开关打开可以非常方便地定位问题系统无关可以针对不同操作系统有不同的实现这对于跨平台的应用非常有帮助。 对于C语言我们可以用dlsym去修改动态链接的函数备注dlsym函数是GNU扩展但dlsym的最大劣势仍然是只能在Linux下使用那么有没有一套跨平台的方案可以在所有平台上运行呢其实也是有的。 那就是通过宏定义的方式将malloc/free这些函数替换成我们自己实现的钩子函数。比如我们有如下定义 //mcheck.h #ifndef _MCHECK_H_ #define _MCHECK_H_#includestddef.hvoid mcheck_initialize(); void mcheck_terminate();void *malloc_hook(size_t size, const char *file, int line); void *calloc_hook(size_t nmemb, size_t size, const char *file, int line); void *realloc_hook(void *ptr, size_t size, const char *file, int line); void free_hook(void *p, const char *file, int line);#define malloc(size) malloc_hook(size, __FILE__, __LINE__) #define calloc(nmemb, size) calloc_hook(nmemb, size, __FILE__, __LINE__) #define realloc(ptr, size) realloc_hook(ptr, size, __FILE__, __LINE__) #define free(p) free_hook(p, __FILE__, __LINE__)#endif由于宏定义是直接替换因此有了上面的代码在执行malloc的时候实际上执行的是malloc_hook函数。而我们只需要在实现malloc_hook/free_hook的时候加上一些统计信息就行了。 在此之前我们封装一个链表用来存储每次申请内存的地址以及申请内存的大小在每次申请内存的时候向链表添加一条数据每次释放的时候将对应的记录删除掉那么当程序结束如果链表还有数据那就是没有释放的泄露部分的内存。 当然你也可以用其他的数据接口来存储这里为了简单演示就直接使用链表了。 // meminfo.h #ifndef _MEMINFO_H_ #define _MEMINFO_H_#includestddef.h #includestdio.h #includestdlib.htypedef enum mcheck_errcode_t {MCHECK_SUCCESS,MCHECK_FAILED, }mcheck_errcode_t;typedef struct mcheck_caller_t {const char *file;int line;const char *func; } mcheck_caller_t;typedef struct mcheck_meminfo {void *address;size_t size;mcheck_caller_t caller; }mcheck_meminfo;typedef struct mcheck_mem_list {mcheck_meminfo mem_info;struct mcheck_mem_list *next; }mcheck_mem_list;int mcheck_mem_list_create(mcheck_mem_list **list); int mcheck_mem_list_add(mcheck_mem_list *mlist, mcheck_meminfo mem_info); mcheck_mem_list *mcheck_mem_list_get(mcheck_mem_list *mlist, void *address); int mcheck_mem_list_delete(mcheck_mem_list *mlist, void *address); int mcheck_list_size(mcheck_mem_list *mlist); void mcheck_list_report_leak(mcheck_mem_list *mlist); void mcheck_list_destory(mcheck_mem_list *mlist); void init_report_file();#endif定义如下 //meminfo.c #include meminfo.hint mcheck_mem_list_create(mcheck_mem_list **mlist){if (*mlist ! NULL) {mcheck_list_destory(*mlist);}*mlist (mcheck_mem_list *)calloc(1, sizeof(mcheck_mem_list));if (*mlist NULL) {return MCHECK_FAILED;}(*mlist)-next NULL;return MCHECK_SUCCESS; }int mcheck_mem_list_add(mcheck_mem_list *mlist, mcheck_meminfo mem_info) {mcheck_mem_list *node NULL;mcheck_mem_list_create(node);node-mem_info mem_info;if (mlist NULL){mlist node;return MCHECK_SUCCESS;}while (mlist-next ! NULL){mlist mlist-next;}mlist-next node;return MCHECK_SUCCESS; }mcheck_mem_list *mcheck_mem_list_get(mcheck_mem_list *mlist, void *address){if (mlist NULL) {return NULL;}mcheck_mem_list *node mlist;while (mlist ! NULL) {if (address mlist-mem_info.address) {return node;}mlist mlist-next;}return NULL; }int mcheck_mem_list_delete(mcheck_mem_list *mlist, void *address){if (mlist NULL) {return MCHECK_FAILED;}mcheck_mem_list *current mlist;mcheck_mem_list *prev mlist;while (current ! NULL) {if (current-mem_info.address address) {if (mlist current) {if (current-next NULL) {mlist NULL;} else {mlist mlist-next;}} else {prev-next current-next;}free(current);return MCHECK_SUCCESS;}prev current;current current-next;}return MCHECK_FAILED; }int mcheck_list_size(mcheck_mem_list *mlist){if (mlist NULL) {return 0;}int size 0;while(mlist-next ! NULL){size;mlist mlist-next;}return size; }void mcheck_list_destory(mcheck_mem_list *mlist){if (mlist NULL) {return;}mcheck_mem_list *current mlist;mcheck_mem_list *prev mlist;while (prev ! NULL) {current current-next;free(prev);prev current;}mlist NULL; }static char *get_report_filename(){char *fname getenv(MCHECK_TRACE);if (fname NULL) {fname mcheck.rpt;}return fname; }void init_report_file(){char *fname get_report_filename();FILE *fp NULL;fp fopen(fname, w);fclose(fp); }static void write_report_file(char *message){char *fname get_report_filename();FILE *fp NULL;fp fopen(fname, a);fprintf(fp, %s\n, message);fflush(stdout);fclose(fp); }void mcheck_list_report_leak(mcheck_mem_list *mlist){if (mcheck_list_size(mlist) 0){write_report_file(All memory was free, congratulations, well done!);return;}write_report_file(Memory Not Free:);write_report_file(-----------------------------);write_report_file(\tAddress\t\tSize\t\tCaller);mlist mlist-next;while (mlist ! NULL){mcheck_meminfo mem_info mlist-mem_info;char message[1024] {0};sprintf(message, \t%p\t%lu\tat\t%s:%d[%s], mem_info.address, mem_info.size, mem_info.caller.file, mem_info.caller.line, mem_info.caller.func);write_report_file(message);mlist mlist-next;} }以上代码逻辑比较简单 就不一一解释了。接下来实现一下钩子函数 #includestdio.h #includemalloc.h #include meminfo.hstatic mcheck_mem_list *mlist NULL;void mcheck_initialize() {init_report_file();mcheck_mem_list_create(mlist); }void mcheck_terminate(){mcheck_list_report_leak(mlist);mcheck_list_destory(mlist); }void *malloc_hook(size_t size, const char *file, int line) {void *p malloc(size);char buff[128] {0};mcheck_meminfo meminfo {0};mcheck_caller_t caller {0};caller.file file;caller.line line;caller.func malloc;meminfo.address p;meminfo.size size;meminfo.caller caller;mcheck_mem_list_add(mlist, meminfo);return p; }void *calloc_hook(size_t nmemb, size_t size, const char *file, int line) {void *p calloc(nmemb, size);char buff[128] {0};mcheck_meminfo meminfo {0};mcheck_caller_t caller {0};caller.file file;caller.line line;caller.func calloc;meminfo.address p;meminfo.size nmemb*size;meminfo.caller caller;mcheck_mem_list_add(mlist, meminfo);return p; }void *realloc_hook(void *ptr, size_t size, const char *file, int line) {void *p realloc(ptr, size);char buff[128] {0};mcheck_meminfo meminfo {0};mcheck_caller_t caller {0};caller.file file;caller.line line;caller.func realloc;meminfo.address p;meminfo.size size;meminfo.caller caller;mcheck_mem_list_add(mlist, meminfo);mcheck_mem_list_delete(mlist, ptr);return p; }void free_hook(void *p, const char *file, int line){mcheck_mem_list_delete(mlist, p);free(p); }如上所示我们会在每次申请内存之前收集其调用栈信息并且封装了mcheck_initialize和mcheck_terminate两个接口函数我们只需要在程序里调用这两个函数就能检测出内存泄露的问题。 类似与下面这种 #include mcheck.hint main(void){mcheck_initialize();//your codemcheck_terminate();return 0; }下面我们用一个具体的示例演示一下 #include mcheck.hint main(void){mcheck_initialize();void *p1 malloc(10);void *p2 malloc(20);free(p1);//free(p2);void *p3 malloc(30);free(p3);void *p4 calloc(1, 64);void *p5 malloc(32);void *p6 realloc(p5, 128);mcheck_terminate();return 0;我们注意在第1行包含了头文件并在第4行和14行分别调用了mcheck的接口这样的话就可以检测出这个过程中出现的内存泄露问题以上代码运行会产生一个名为mcheck.rpt的报告内容如下 Memory Not Free: -----------------------------Address Size Caller0x1fde0b0 20 at mcheck_sample.c:6[malloc]0x1fde300 64 at mcheck_sample.c:11[calloc]0x1fde390 128 at mcheck_sample.c:13[realloc]它告诉我们第61113行分别出现了内存泄露大小是多少调用的那么函数申请的内存还是比较详细的。 但是这种方式也有缺陷。首先就是调用栈只有一层不能打印出更深层的调用栈不利于复杂程序的问题排查。其次是如果要使mcheck生效必须每个.c里都要include该头文件对于第三方库是没有办法检测到的因此使用面也是比较有限。 本专栏知识点是通过零声教育的系统学习进行梳理总结写下文章对C/C课程感兴趣的读者可以点击链接查看详细的服务C/CLinux服务器开发/高级架构师
http://www.tj-hxxt.cn/news/141572.html

相关文章:

  • 哪个网站可以做社工试题网页设计作品特色及亮点
  • app的网站域名注册便宜高端网站设计
  • 一起装修网官方网站公司网站建设的范文
  • 个人信息网站模板商品图片网站开发
  • 如何在电影网站中做淘客wordpress 虚拟商品插件
  • 丽水市做网站的网站数据库模板下载
  • 临汾哪里有做网站的贵州企业网站建设公司
  • 电子政务网站建设收到网站代码后怎么做
  • 字母logo设计网站创新的大良网站建设
  • 网站备案期间可以用二级域名访问网站吗哈尔滨网站设计定制
  • 网站开发入门书如何做内容收费的网站
  • 网站建设需要材料开发游戏用什么编程软件
  • wordpress数据库密码加密多少位太原网站seo顾问
  • 国内免费产品发布网站工作室建设规划
  • 做网站公司上什么平台宁波网络公司网站建s
  • 温州做网站哪家公司好甘肃锦华建设集团网站
  • 在线流程图网站怎么做网站首页设计欣赏
  • 维护公司网站建设网站拥有者查询
  • wordpress 主图截图网络优化网站建设学习
  • 澄城县城乡建设局网站儿童主题网站的内容建设
  • 网站营销外包公司简介长沙传媒公司招聘
  • 我的南京网站wordpress企业魔板
  • 网站超级外链wordpress 第三方支付
  • 南京网站开发询南京乐识如何注册公司注册公司需要什么
  • 全省建设信息网站参考消息电子版报纸
  • 成都建站模板网站开发怎么破解wordpress图片防盗链
  • 如何用ps做网站导航条项目管理软件project手机版
  • 如何利用开源代码做网站广州比较好的外贸公司有哪些
  • 在百度上如何上传自己的网站品牌设计网站公司
  • 网站 优化 件大企业网站建设公司排名