《深入剖析Nginx》一2.5 加桩调试
本节书摘来异步社区《深入剖析Nginx》一书中的第2章,第2.5节,作者: 高群凯 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.5 加桩调试
深入剖析Nginx
如果我们对代码做过单元测试,那么肯定知道加桩的概念,简单点说就是为了让一个模块执行起来,额外添加的一些支撑代码。比如,我要简单测试一个实现某种排序算法的子函数的功能是否正常,那么我也许需要写一个main()函数,设置一个数组,提供一些乱序的数据,然后利用这些数据调用排序子函数(假设它提供的接口就是对数组的排序),然后printf打印排序后的结果,看是否排序正常,所有写的这些额外代码(main()函数、数组、printf打印)就是桩代码。
上面提到的这种用于单元测试的方法,同样也可以用来深度调试Nginx内部逻辑,而且Nginx很多的基础实现(比如slab机制、红黑树、chain链、array数组等)都比较独立,要调试它们只需提供少量的桩代码即可。
以Nginx的slab机制为例,我们通过下面所提供的这些桩代码即可调试该功能的具体实现。Nginx 的 slab 机制用于对多进程共享内存的管理,不过单进程也是一样的执行逻辑,除了加/解锁直通以外(即加锁时必定成功),所以我们采取最简单的办法,直接在 Nginx 本身的main()函数内插入我们的桩代码。当然,必须根据具体情况把桩代码放在合适的调用位置,比如这里的slab机制就依赖一些全局变量(像ngx_pagesize等),所以需要把桩代码的调用位置放在这些全局变量的初始化之后。
197: 代码片段2.5-1,文件名: nginx.c
198: void ngx_slab_test()
199: {
200: ngx_shm_t shm;
201: ngx_slab_pool_t *sp;
202: u_char *file;
203: void *one_page;
204: void *two_page;
205:
206: ngx_memzero(&shm, sizeof(shm));
207: shm.size = 4 * 1024 * 1024;
208: if (ngx_shm_alloc(&shm) != NGX_OK) {
209: goto failed;
210: }
211:
212: sp = (ngx_slab_pool_t *) shm.addr;
213: sp->end = shm.addr + shm.size;
214: sp->min_shift = 3;
215: sp->addr = shm.addr;
216:
217: #if (NGX_HAVE_ATOMIC_OPS)
218: file = NULL;
219: #else
220: #error must support NGX_HAVE_ATOMIC_OPS.
221: #endif
222: if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
223: goto failed;
224: }
225:
226: ngx_slab_init(sp);
227:
228: one_page = ngx_slab_alloc(sp, ngx_pagesize);
229: two_page = ngx_slab_alloc(sp, 2 * ngx_pagesize);
230:
231: ngx_slab_free(sp, one_page);
232: ngx_slab_free(sp, two_page);
233:
234: ngx_shm_free(&shm);
235:
236: exit(0);
237: failed:
238: printf("failed.\n");
239: exit(-1);
240: }
241: …
353: if (ngx_os_init(log) != NGX_OK) {
354: return 1;
355: }
356:
357: ngx_slab_test();
358: …
上面是修改之后的nginx.c源文件,直接make后生成新的Nginx,不过这个可执行文件不再是一个Web服务器,而是一个简单的调试slab机制的辅助程序。可以看到,程序在进入main()函数后先做一些初始化工作,然后通过ngx_slab_test()函数调入到桩代码内执行调试逻辑,完成既定目标后便直接exit()退出整个程序。
正常运行时,Nginx本身对内存的申请与释放是不可控的,所以直接去调试Nginx内存管理的slab机制的相关代码逻辑非常困难,利用这种加桩的办法,ngx_slab_alloc()申请内存和ngx_slab_free()释放内存都能精确控制,对每一次内存的申请或释放后,slab机制的内部结构发生了怎样的变化都能准确地掌握,对其相关逻辑的理解也就没有那么困难了。
《深入剖析Nginx》一2.5 加桩调试相关推荐
- nginx模块_使用gdb调试nginx源码
工欲善其事必先利其器,如何使用调试工具gdb一步步调试nginx是了解nginx的重要手段. ps:本文的目标人群是像我这样初接触Unix编程的同学,如果有什么地方错误请指正. 熟悉gdb的使用 这里 ...
- 《深入剖析NGINX》学习记录
1.HTTP服务基本特性 处理静态页面请求; 处理index首页请求 对请求目录进行列表显示; 支持多进程间的负载均衡; 对打开文件描述符进行缓存(提高性能); 对反向代理进行缓存(加速); 支持gz ...
- 深入剖析nginx时间缓存
本文适合对nginx实现原理比较感兴趣的同学阅读,需要具备一定的服务端编程知识. 一.背景 在服务器开发领域,时间的准确度关系到系统能否正常运行,尤其是当系统中存在超时事件需要处理时.但是系统时间的获 ...
- 深入剖析nginx第141页
- nginx源码分析--使用GDB调试
在学习优秀的源代码时是少不了源码的跟踪与调试,它不仅是我们解决程序bug的有效途径,也是我们理解.学习优秀源码的有效途径. 本文主要介绍一些源码调试的方法,并结合Nginx源码进行示例. 1,利用GD ...
- Nginx学习之十四-GDB调试Nginx初试
本文的测试环境: Win7+虚拟机VMWareVMware-workstation-full-7.1.4-385536+Ubuntu12.04 Nginx-1.4.0 要想有效的研究Nginx源码,必 ...
- Nginx开启/关闭Core文件及调试
1. Nginx生成core的配置 1.ulimit -a 可以查看系统core文件的大小限制(第一行),core文件大小设置为0,即没有打开core dump设置. core file size ...
- Nginx学习之十三-负载均衡-IP哈希策略剖析
前面介绍过nginx负载均衡的加权轮询策略(http://blog.csdn.net/xiajun07061225/article/details/9318871),它是Nginx负载均衡的基础策略, ...
- nginx中location介绍
http://www.cnblogs.com/lidabo/p/4169396.html 博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 :: 管理 :: ...
最新文章
- 图解ARP协议分析实例
- dw1000 配置无法通过
- Codeforces Round #527 (Div. 3) 总结 A B C D1 D2 F
- Magento: 根据产品属性加载产品信息 Load A Category or Product by an Attribute
- BGP ——路由过滤+路由聚合(讲解+配置)
- 重装系统后只有C盘,怎么处理?
- android adbd分析,android6.0 adbd深入分析(三)adb root重启adbd流程
- netty 使用阻塞发送_「解」互联网大厂Java面试题——Netty 面试题解析
- [原创]Silverlight与SQLite数据库的互操作(CURD完全解析)[Final]
- html预览页面做成a4纸,如何在A4纸张尺寸页面制作HTML页面?
- linux redis玂家链接不上,Unicode编码的熟悉与研究过程(内附全部汉字编码列表)...
- 腾讯bugly的使用,以及全局抓包配置
- EMD(Exploiting Modification Direction)
- 短视频的海绵宝宝配音怎么制作?这可能是最容易上手的配音教程
- 谈谈UCloud保障数据安全的七种“武器”
- 《如何优化项目一》:页面缓存优化
- Linux 命令(189)—— init 命令
- 前端HTML调用jQuery库,属性操作:更换图片、添加字体样式(前端:HTML搭配jQuery系列教程六)
- 【有利可图网】PS教程:利用PS分分钟将照片变成中国风古画效果
- 用户产生内容(UGC)和用户创建市场(UGM)