PHP网页设计PHP stream未能实时清算现场招致Core的...
工具程序用来显示 Rasmus Lerdorf 的个人履历,以及统计网页流量。同事发明一个在利用set_error_handler的时分, 能100%重现的core, 提炼后的重古代码以下(情况必需不克不及会见internet):
<?php
function err_handler(){
exit;
return true;
}
set_error_handler('err_handler');
$client = file_get_contents("http://www.laruence.com/ServiceNoWse.asmx?WSDL");
这段代码, 放在webServer中, 第一次会见不会有事, 第二第三次的时分就会出core.
gdb跟踪今后发明, core出在php_stream_display_wrapper_errors函数中, 对err_stack中的毛病信息字符串做处置的时辰, core的仓库以下:
#0 0x000000302af6ff20 in strlen () from /lib64/tls/libc.so.6
#1 0x0000002a989d97c1 in php_stream_display_wrapper_errors (wrapper=0x2a98e884a0, path=Variable "path" is not available.
) at /home/huixc/package/php-5.2.14/main/streams/streams.c:151
#2 0x0000002a989dca22 in _php_stream_open_wrapper_ex (path=0x76e7c8 "http://www.laruence.com/ServiceNoWse.asmx?WSDL", mode=0x2a98ae3087 "rb", options=8, opened_path=0x0,
context=0x76e808) at /home/huixc/package/php-5.2.14/main/streams/streams.c:1893
#3 0x0000002a98966541 in zif_file_get_contents (ht=-1729541984, return_value=0x76e738, return_value_ptr=Variable "return_value_ptr" is not available.
) at /home/huixc/package/php-5.2.14/ext/standard/file.c:541
#4 0x0000002a98a2c05e in zend_do_fcall_common_helper_SPEC (execute_data=0x7fbfffca30) at /home/huixc/package/php-5.2.14/Zend/zend_vm_execute.h:200
#5 0x0000002a98a2b671 in execute (op_array=0x769890) at /home/huixc/package/php-5.2.14/Zend/zend_vm_execute.h:92
#6 0x0000002a98a0c734 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/huixc/package/php-5.2.14/Zend/zend.c:1134
#7 0x0000002a989c965d in php_execute_script (primary_file=0x7fbfffef00) at /home/huixc/package/php-5.2.14/main/main.c:2036
#8 0x0000002a98a9bd36 in php_handler (r=0x8f1ba8) at /home/huixc/package/php-5.2.14/sapi/apache2handler/sapi_apache2.c:639
经由半个多小时的跟踪, 终究找到缘由
是由于, 在PHP中, 关于exit, 实际上是借助了set/longjmp来完成用户剧本加入今后, 抵达扫尾任务, 而关于失足代码出是依据wrapper的err_count计数来肯定有几何毛病信息要输入.
而且, 在输入完毛病信息今后, 清空wrap的毛病信息, 置零毛病计数.
void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
{
if (wrapper) {
/* tidy up the error stack */
int i;
for (i = 0; i < wrapper->err_count; i++) {
efree(wrapper->err_stack);
}
if (wrapper->err_stack) {
efree(wrapper->err_stack);
}
wrapper->err_stack = NULL;
wrapper->err_count = 0;
}
}
而, 由于在实际毛病信息以后, 会紧接着触发php_error_docref1, 继而触发代码中设置的error_handler, 而在handler中, 却挪用了exit, 终究longjmp到了soap处置时辰设置的跳转点, 形成跳过了对 php_stream_tidy_wrapper_error_log 的挪用, 所以招致第二次再来恳求的时分, err_count并没有准确的被初始化为零, 仍是坚持着前次恳求的毛病数.
因而, 在输入毛病信息的时分,
......
for (i = 0, l = 0; i < wrapper->err_count; i++) {
l += strlen(wrapper->err_stack); //出core了
if (i < wrapper->err_count - 1) {
l += brlen;
}
}
临时来讲, 处理这个举措, 可以在streams的php_stream_display_wrapper_errors函数挪用php_error_docref1之前失落后用php_stream_tidy_wrapper_error_log;
我的这套线路可能跟许多学习PHP的爱好者不谋而合,这也算是一个循序渐进的学习过程,不过新手不要看到上面的概括就以为学习蛮简单的,默默在此不得不对您稍微泼一下冷水,任何东西其实都不简单。 要进行开发,搭建环境是首先需要做的事,windows下面我习惯把环境那个安装在C盘下面,因为我配的环境经常出现诡异事件,什么事都没做环境有的时候就不能用啦。 如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了, 找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。 其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎 有位前辈曾经跟我说过,phper 至少要掌握200个函数 编起程序来才能顺畅点,那些不熟悉的函数记不住也要一拿手册就能找到。所以建议新手们没事就看看php的手册(至少array函数和string函数是要记牢的)。 先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。 做为1门年轻的语言,php一直很努力。 刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。 建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。 爱上php,他也会爱上你。 真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎, 环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。 环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。 如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了, 本文当是我的笔记啦,遇到的问题随时填充 环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。 做为1门年轻的语言,php一直很努力。 遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。 你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
页:
[1]