问题1: 配置解析过程使用ngx_cycle->pool申请内存保存配置,结果造成野指针。

背景:需求开发过程,有一些结构需要在配置解析阶段保存,然后可以动态修改。看原来的代码配置解析都是使用cf->pool进行内存申请,但动态修改的过程显然拿不到cf,于是想到了一个全局的内存池ngx_cycle->pool,想当然的认为ngx_cycle的生命周期是从配置解析开始到进程退出,期间是不会释放ngx_cycle->pool的,但其实是错误的,具体原因如下:

nginx的启动源码简化后如下所示,从代码中的注释可以看出原来配置解析前后ngx_cycle变量中的pool不是同一个:

int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_cycle_t *cycle, init_cycle;
...
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
...
//配置解析前创建的pool,解析过程拿到的ngx_cycle->pool就是这个
init_cycle.pool = ngx_create_pool(, log);
if (init_cycle.pool == NULL) {
return ;
}
...
cycle = ngx_init_cycle(&init_cycle);
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(, "configuration file %s test failed",
init_cycle.conf_file.data);
} return ;
}
...
ngx_cycle = cycle;
}

其中配置解析在ngx_init_cycle里面完成

ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
ngx_cycle_t *cycle, **old;
...
log = old_cycle->log;
//这个pool放在cycle中带出去,配置解析之后赋值给ngx_cycle
pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (pool == NULL) {
return NULL;
}
pool->log = log; cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
if (cycle == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->pool = pool;
cycle->log = log;
cycle->old_cycle = old_cycle;
.....
配置解析
...
return cycle;
}

结论:ngx_cycle的周期不能简单的认为是从进程启动到退出,其pool在配置解析前后是两个值。在配置处理阶段ngx_cycle表示的是老的cycle,启动阶段完成才会换成新的cycle,这也是为什么在启动阶段调用ngx_http_cycle_get_module_main_conf会把设备搞挂的原因。

问题2:检视代码的时候发现ngx_array_t如果想被反复使用的话,需要注意其内存池的唯一性,不然会内存泄漏。

直接上nginx内核源码

void
ngx_array_destroy(ngx_array_t *a)
{
ngx_pool_t *p; p = a->pool; if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
p->d.last -= a->size * a->nalloc;
} if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
p->d.last = (u_char *) a;
}
}

结论:如果一个nginx的动态数组想在使用过程中调用ngx_array_destroy销毁,然后再ngx_array_init重复利用的话,那么一定要保证这个数组的内存池只给他自己用,否则,ngx_array_destroy中的两个判断都不成立,内存池的这块内存将无法释放。

nginx坑记录的更多相关文章

  1. cefglue埋坑记录

    很少写博客,写的不好,请多多包含,主要是记录工作中的一些问题,和园子里朋友一起讨论学习. 写埋坑记录之前,我先介绍下为什么会使用这个webkit内核的浏览器组件,我是wpf项目使用富文本编辑器,话说w ...

  2. Nginx正确记录post日志的方法

    Nginx正确记录post日志的方法 事实上可以很简单,这取决于把 access_log 放在哪个 location 里面. 一,放到包含fastcgi_pass或proxy_pass的Locatio ...

  3. unionId突然不能获取的踩坑记录

    昨天(2016-2-2日),突然发现系统的一个微信接口使用不了了.后来经查发现,是在网页授权获取用户基本信息的时候,unionid获取失败导致的. 在网页授权获取用户基本信息的介绍中(http://m ...

  4. webapp填坑记录[更新中]

    网上也有许多的 webapp 填坑记录了,这几个月,我在公司正好也做了2个,碰到了一些问题,所以我在这里记录一下我所碰到的问题: meta 头部声明在开发的时候,刚刚创建 HTML 文件,再使用浏览器 ...

  5. CentOS7.4安装MySQL踩坑记录

    CentOS7.4安装MySQL踩坑记录 time: 2018.3.19 CentOS7.4安装MySQL时网上的文档虽然多但是不靠谱的也多, 可能因为版本与时间的问题, 所以记录下自己踩坑的过程, ...

  6. ubuntu 下安装docker 踩坑记录

    ubuntu 下安装docker 踩坑记录 # Setp : 移除旧版本Docker sudo apt-get remove docker docker-engine docker.io # Step ...

  7. SpringBoot + Shiro + shiro.ini 的踩坑记录

    0.写在前面的话 好久没写博客了,诶,好多时候偷懒直接就抓网上的资料丢笔记里了,也就没有自己提炼,偷懒偷懒.然后最近参加了一个网络课程,要交作业的那种,为了能方便看下其他同学的作业,就写了个爬虫把作业 ...

  8. Charles 抓包工具安装和采坑记录

    Charles 抓包工具安装和采坑记录 网络抓包是解决网络问题的第一步,也是网络分析的基础.网络出现问题,第一步肯定是通过抓包工具进行路径分析,看哪一步出现异常.做网络爬虫,第一步就是通过抓包工具对目 ...

  9. tidb使用坑记录

    转载自:https://www.cnblogs.com/linn/p/8459327.html tidb使用坑记录 1.对硬盘要求很高,没上SSD硬盘的不建议使用 2.不支持分区,删除数据是个大坑. ...

随机推荐

  1. Maven clean install 跳过单元测试

    1.使用MVN命令 mvn clean install -DskipTests 或者 mvn clean install -Dmaven.test.skip=true 2.Eclipse中设置clea ...

  2. vuex介绍和vuex数据传输流程

    1.什么是vuex? 公共状态管理:解决多个非父子组件传值麻烦的问题:简单说就是多个页面都能用Vuex中store公共的数据 a.并不是所有的数据都要放在Vuex中,只有各个组件公用的一些数据会放在V ...

  3. android studio配置模拟器

    配置模拟器在Android开发中,肯定是要写好代码看结果的,如果使用as中自带的模拟器太low,启动速度又慢,网上有很多教程推荐使用genymotion模拟器的,可是如果是新手我建议选择更好入门的第三 ...

  4. 判断是否是iframe框架打开登录页, iframe框架着顶部页面刷新

    if (window != top) top.location.href = location.href;

  5. 个人智能家居系统 - MQTT服务器搭建(centOS7.3)

    个人智能家居系统 - MQTT服务器搭建(centOS7.3) 0x00 参考 在CentOS7 上安装mosquitto1.4.1服务器,实现MQTT信息推送功能并增加websocket功能 mos ...

  6. MongoDB与python 交互

    一.安装pymongo 注意 :当同时安装了python2和python3,为区分两者的pip,分别取名为pip2和pip3. 推荐:https://www.cnblogs.com/thunderLL ...

  7. Asc函数与Chr函数

    返回值: Integer    返回字符串中第一个字符的字符代码.    提示: Chr函数可以将一个Ascii码转换为相对应的字符 语法:   Asc(string) string,必须参数,字符串 ...

  8. man cal

    CAL(1)                                                                  CAL(1) NAME       cal - 显示一个 ...

  9. MySQL数据库4Python操作mysql、索引、慢查询日志

    目录 一.Python 操作 mysql 1.1python 操作 mysql 1.2查询数据 1.3增加(添加.更新)数据 1.4修改数据 1.5删除数据 1.6SQL注入问题 1.6.1问题的引入 ...

  10. 【leetcode】1144. Decrease Elements To Make Array Zigzag

    题目如下: Given an array nums of integers, a move consists of choosing any element and decreasing it by ...