原文:memory_limit的一个bug | 风雪之隅

27 Nov 09 memory_limit的一个bug




PHP 5.2x中, 由于错误的选用了zend_atoi, 导致memory_limit不能设置为超过4G的值.


今天同事分享给我一个问题(thans to yanmi), 一段代码(PHP 5.2.11 Linux/X86_64),设置memory_limit为4096M会导致内存耗尽, 而设置4095M就不会. 奇怪的问题呵.


那是怎么回事呢?


问题的原因也很简单, 在PHPSRC/main.c中定义的memory_limit设置项的处理器OnChangeMemoryLimit中, 并没有检测当前的机器字长, 而统一使用了zend_atoi来做为字符串数字化, 这个问题在PHP5.3的版本中已经修正(换成了zend_atol):

  1. static PHP_INI_MH(OnChangeMemoryLimit)
  2. {
  3. if (new_value) {
  4. PG(memory_limit) = zend_atoi(new_value, new_value_length);
  5. } else {
  6. PG(memory_limit) = 1<<30; /* effectively, no limit */
  7. }
  8. return zend_set_memory_limit(PG(memory_limit));
  9. }

而, 顾名思义么, atoi是转成整形, 4096M是2的32次方, 发生溢出, 继而环绕成结果为0, zend_atoi代码如下:

  1. ZEND_API int zend_atoi(const char *str, int str_len)
  2. {
  3. int retval;
  4. if (!str_len) {
  5. str_len = strlen(str);
  6. }
  7. retval = strtol(str, NULL, 0);
  8. if (str_len>0) {
  9. switch (str[str_len-1]) {
  10. case 'g':
  11. case 'G':
  12. retval *= 1024;
  13. /* break intentionally missing */
  14. case 'm':
  15. case 'M':
  16. retval *= 1024;
  17. /* break intentionally missing */
  18. case 'k':
  19. case 'K':
  20. retval *= 1024;
  21. break;
  22. }
  23. }
  24. return retval;
  25. }

最后在zend_set_memory_limit的时候, 会错误的设置memory_limit为mm_heap的blok_size, 那结果就肯定远远小与你所预期的4096M了

  1. ....
  2. AG(mm_heap)->limit = (memory_limit >= AG(mm_heap)->block_size) ? memory_limit : AG(mm_heap)->block_size;
  3. ...

最后, 如果是32位的机器, 那确实不算bug, 但现在的机器很多都64了, 最大内存也不再是4GB了, PHP也要与时俱进啊.


PS, 多看别人的代码是有好处的, 今天有学会了intentionally这个单词, ^_^.




分享到: 1

document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?t=" + new Date().getHours();



Related Posts:



Tags: PHP, php bug, php源码分析



Filed in PHP源码分析

memory_limit的一个bug | 风雪之隅的更多相关文章

  1. 【风雪之隅】写在PHP7发布之际一些话 2015-12-02

    做开源也有4,5年的时间了,从最初的 Yaf,到今天的 PHP7,我参与的项目越来越多,使用我代码的用户也越来越多,明天就要发布的PHP7,绝对是我从事开源以来的一个最重要里程碑,我应该纪念一下今天, ...

  2. Tomcat一个BUG造成CLOSE_WAIT

    之前应该提过,我们线上架构整体重新架设了,应用层面使用的是Spring Boot,前段日子因为一些第三方的原因,略有些匆忙的提前开始线上的内测了.然后运维发现了个问题,服务器的HTTPS端口有大量的C ...

  3. MySQL关于exists的一个bug

    今天碰到一个很奇怪的问题,关于exists的, 第一个语句如下: SELECT ) FROM APPLY t WHERE EXISTS ( SELECT r.APPLY_ID FROM RECORD ...

  4. 由一个bug引发的SQLite缓存一致性探索

    问题 我们在生产环境中使用SQLite时中发现建表报“table xxx already exists”错误,但DB文件中并没有该表.后面才发现这个是SQLite在实现过程中的一个bug,而这个bug ...

  5. Win10系统菜单打不开问题的解决,难道是Win10的一个Bug ?

    Win10左下角菜单打不开,好痛苦,点击右下角的时间也没反应,各种不爽,折磨了我好几天,重装又不忍心,实在费劲,一堆开发环境要安装,上网找了很多方法都不适用.今天偶然解决了,仔细想了下,难道是Win1 ...

  6. 你可能不知道的 NaN 以及 underscore 1.8.3 _.isNaN 的一个 BUG

    这篇文章并不在我的 underscore 源码解读计划中,直到 @pod4g 同学回复了我的 issue(详见 https://github.com/hanzichi/underscore-analy ...

  7. 标准模板库(STL)的一个 bug

    今天敲代码的时候遇到 STL 的一个 bug,与 C++ 的类中的 const 成员变量有关.什么,明明提供了默认的构造函数和复制构造函数,竟然还要类提供赋值运算符重载.怎么会这样? 测试代码 Tes ...

  8. 是uibutton跟tableviewcell同步使用一个bug

    这个问题是uibutton跟tableviewcell同步使用一个bug,不关delay一点毛事,证据就是点击事件没问题,so,搜到一个方法解决了这个问题.uibutton分类symbian2+ios ...

  9. 在chrome下-webkit-box布局的一个bug

    chrome,也就是webkit内核下作的检测, chrome版本是40, -webkit-box这种布局在移动端用的比较多,主要是因为pc端的浏览器内核参差不齐. 因为在写HTML的时候看上了-we ...

随机推荐

  1. POJ1325 Machine Schedule(二分图最小点覆盖集)

    最小点覆盖集就是在一个有向图中选出最少的点集,使其覆盖所有的边. 二分图最小点覆盖集=二分图最大匹配(二分图最大边独立集) 这题A机器的n种模式作为X部的点,B机器的m种模式作为Y部的点: 每个任务就 ...

  2. BZOJ3619 : [Zjoi2014]璀灿光华

    终于把省选时的遗憾补上了… 对于构造立方体: 首先BFS构出底层,然后再逐层构造立方体 对于计算: $O(n^6)$爆搜即可. #include<cstdio> #include<c ...

  3. Robotium 测试方法

    1.检查CheckBox 是否选上,用solo.isCheckBoxChecked( “text” ). 有时候checkBox 没有相关的text,这时要用solo.isCheckBoxChecke ...

  4. 达成成就:排名和AC数相同

    233333 纪念一下.(268会不会是幸运数字呢0.0

  5. vim molokai配色方案(调过)

    " Vim color file " " Author: Tomas Restrepo <tomas@winterdom.com> " " ...

  6. Shell之sed用法 转滴

    通过例子学习sed的用法 1,sed介绍    sed可删除(delete).改变(change).添加(append).插入(insert).合.交换文件中的资料行,或读入其它档的资料到 文> ...

  7. php5全版本绕过open_basedir读文件脚本

    这是前段时间写的代码了(http://www.weibo.com/1074745063/ByAPqj7s0),最近一直忙着和几个同学一起做非安全类的创业项目.所以也没拿到JAE.SAE测试一下. 不说 ...

  8. Spring对加载的bean之间循环依赖的处理

    根据下面文档的叙述,简言之: 对于相互之间通过构造函数注入相互循环依赖的情况,Spring会抛出BeanCurrentlyInCreationException错误. 如果AB两个beans是通过属性 ...

  9. [排错] Status error 2850

    前几天重新搭建了APAC的Netbackup, 终于可以备份成功了, 但是今天在做还原的时候遇到了些小问题,记录下来. 1. 在CNHZSRV04BPO上执行还原的时候报下面的错误. 2. 经过检查发 ...

  10. CruiseControl.Net学习记录

    一.下载 官网 二.安装 本文版本:1.8.5.0 运行安装程序,按照提示"下一步”,直到完成即可. 安装完毕之后, 生成一个windows服务,CruiseControl.NET Serv ...