搜尋
首頁php教程php手册PHP stream未能及时清理现场导致Core的bug

 

  同事发现一个在使用set_error_handler的时候, 能100%重现的core, 提炼后的重现代码如下(环境必须不能访问internet):

 

  

  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 err_count; i++) {

  efree(wrapper->err_stack[i]);

  }

  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 err_count; i++) {

  l += strlen(wrapper->err_stack[i]); //出core了

  if (i err_count - 1) {

  l += brlen;

  }

  }

 

  暂时来说, 解决这个办法, 可以在streams的php_stream_display_wrapper_errors函数调用php_error_docref1之前掉后用php_stream_tidy_wrapper_error_log;



陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

北端:融合系統,解釋
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
4 週前By尊渡假赌尊渡假赌尊渡假赌
<🎜>掩蓋:探險33-如何獲得完美的色度催化劑
2 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具