Edit report at https://bugs.php.net/bug.php?id=60689&edit=1
ID: 60689 Comment by: phpmpan at mpan dot pl Reported by: valentiny510 at yahoo dot es Summary: Return $this double quoted __toString Status: Bogus Type: Bug Package: Class/Object related Operating System: windows xp PHP Version: 5.3.8 Block user comment: N Private report: N New Comment: > Probably because of some faulty C code using an invalid pointer. Nope. This is caused by faulty PHP code that valentiny510 presented us earlier. And it's not because of invalid pointer. As backtrace shows, it's stack overflow. However I agree that setting this report to bogus without a reason is not a nice thing. `__toString` documentation says nothing about recursive calls. It only says that the return type should be a string or `E_RECOVERABLE_ERROR` happens. In this case this requirement is satisfied. Therefore what should we serach for in the manual? While this is an obvious error in user's code, a similar situation in other functions does not cause a low-level crash. PHP nicely handles this and emits an error. But in this specific case this is not working. From PHP sources point of view it's obvious that different things handle those cases, but it's not so easy to see or expected from users point of view. Therefore this should be either fixed or, if fixing this would require too much work, ignoring. But ignoring with a specific reason of error being too hard to fix. Previous Comments: ------------------------------------------------------------------------ [2012-01-18 09:51:56] harrygriff at griffcomp dot com I just love when after one week somebody come and renspond with a copy/paste message saying is not a bug with no arguments. My tests reveal that this script completely crush the apache server and dont't even warn about it. Apache logs show this line.. [Wed Jan 18 10:36:53 2012] [notice] Parent: child process exited with status 3221225477 -- Restarting. .......etc... After some time investigating I found this answer.. The 3221225477 is C0000005 in hex notation, which is just the good old general protection fault, caught by the windows kernel. In other words: Apache itself, some Apace module or any of the DLLs used by Apache or its modules crashed. Probably because of some faulty C code using an invalid pointer. So if only few lines of PHP code can crush/restart the server don't tell me is "not a bug"... You can blame apache or windows kernel but the point is the error started with an PHP script.. Please check this Mike before respond ------------------------------------------------------------------------ [2012-01-17 19:19:00] m...@php.net Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php ------------------------------------------------------------------------ [2012-01-10 16:43:25] valentiny510 at yahoo dot es Looking into the source (zend_object_handlers.c) you don´t need the debugger: ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* {{{ */ { zval *retval; zend_class_entry *ce; switch (type) { case IS_STRING: ce = Z_OBJCE_P(readobj); if (ce->__tostring && (zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) { if (EG(exception)) { if (retval) { zval_ptr_dtor(&retval); } zend_error(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name); return FAILURE; } if (Z_TYPE_P(retval) == IS_STRING) { INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_ZVAL(writeobj, retval, 1, 1); if (Z_TYPE_P(writeobj) != type) { convert_to_explicit_type(writeobj, type); } return SUCCESS; } else { zval_ptr_dtor(&retval); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_EMPTY_STRING(writeobj); zend_error(E_RECOVERABLE_ERROR, "Method %s::__toString() must return a string value", ce->name); return SUCCESS; } } return FAILURE; case IS_BOOL: INIT_PZVAL(writeobj); ZVAL_BOOL(writeobj, 1); return SUCCESS; case IS_LONG: ce = Z_OBJCE_P(readobj); zend_error(E_NOTICE, "Object of class %s could not be converted to int", ce->name); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_LONG(writeobj, 1); return SUCCESS; case IS_DOUBLE: ce = Z_OBJCE_P(readobj); zend_error(E_NOTICE, "Object of class %s could not be converted to double", ce->name); INIT_PZVAL(writeobj); if (readobj == writeobj) { zval_dtor(readobj); } ZVAL_DOUBLE(writeobj, 1); return SUCCESS; default: INIT_PZVAL(writeobj); Z_TYPE_P(writeobj) = IS_NULL; break; } return FAILURE; } ------------------------------------------------------------------------ [2012-01-10 15:25:37] phpmpan at mpan dot pl Confirmed for 5.3.8 and for 2011/01/04 snapshots of 5.3, 5.4 and trunk, on Arch64. Inifnite recursion causing SIGSEGV. Partial backtrace: ----------- BEGIN BACKTRACE ----------- #0 0x00000000005d853e in zend_mm_search_large_block (heap= Cannot access memory at address 0x7fffff7fefc0 ) at src-trunk/Zend/zend_alloc.c:1804 #1 0x00000000005d8a50 in _zend_mm_alloc_int (heap=0xad72b0, size=32, __zend_filename=0x86c908 "src-trunk/Zend/zend.c", __zend_lineno=264, __zend_orig_filename=0x0, __zend_orig_lineno=0) at src-trunk/Zend/zend_alloc.c:1934 #2 0x00000000005da624 in _emalloc (size=32, __zend_filename=0x86c908 "src-trunk/Zend/zend.c", __zend_lineno=264, __zend_orig_filename=0x0, __zend_orig_lineno=0) at src-trunk/Zend/zend_alloc.c:2425 #3 0x000000000060dfd9 in zend_make_printable_zval (expr=0x7ffff6777618, expr_copy=0x7fffff7ff220, use_copy=0x7fffff7ff21c) at src-trunk/Zend/zend.c:264 #4 0x0000000000712d75 in ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER ( execute_data=0x7ffff6710510) at src-trunk/Zend/zend_vm_execute.h:25868 #5 0x000000000064e123 in execute (op_array=0x7ffff7fcbf68) at src-trunk/Zend/zend_vm_execute.h:410 #6 0x00000000005fd1de in zend_call_function (fci=0x7fffff7ff6e0, fci_cache=0x7fffff7ff670) at src-trunk/Zend/zend_execute_API.c:958 #7 0x000000000062edc1 in zend_call_method (object_pp=0x7fffff7ff798, obj_ce=0x7ffff7fcab98, fn_proxy=0x7ffff7fcad00, function_name=0x872790 "__tostring", function_name_len=10, retval_ptr_ptr=0x7fffff7ff7a8, param_count=0, arg1=0x0, arg2=0x0) at src-trunk/Zend/zend_interfaces.c:97 #8 0x00000000006462e8 in zend_std_cast_object_tostring (readobj=0x7ffff6777618, writeobj=0x7fffff7ff960, type=6) at src-trunk/Zend/zend_object_handlers.c:1494 #9 0x000000000060e0b4 in zend_make_printable_zval (expr=0x7ffff6801598, expr_copy=0x7fffff7ff960, use_copy=0x7fffff7ff95c) at src-trunk/Zend/zend.c:267 #10 0x0000000000712d75 in ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER ( execute_data=0x7ffff6710428) at src-trunk/Zend/zend_vm_execute.h:25868 #11 0x000000000064e123 in execute (op_array=0x7ffff7fcbf68) at src-trunk/Zend/zend_vm_execute.h:410 #12 0x00000000005fd1de in zend_call_function (fci=0x7fffff7ffe20, fci_cache=0x7fffff7ffdb0) at src-trunk/Zend/zend_execute_API.c:958 (#7-#12 repeats) ------------ END BACKTRACE ------------ ------------------------------------------------------------------------ [2012-01-09 06:16:37] valentiny510 at yahoo dot es Description: ------------ If you try to return $this double quoted in __toString break all the system and does not even throw any exception or log anything. my php.ini have error_reporting = E_ALL | E_STRICT display_errors = On display_startup_errors = On log_errors = On report_memleaks = On report_zend_debug = 1 Test script: --------------- class test { public function __toString ( ) { return "$this"; } } $test = new test; echo $test; Expected result: ---------------- the string "$this" or the error exception Actual result: -------------- The server break completely and does not output nothing, not even the error log. The browser say "The connection has been reset". (The apache server is still logging the requests) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=60689&edit=1