ext/reflection causes stack overflow under valgrind when CC=clang #11713
Copy link
Copy link
Closed
Description
Description
Please refer to this reproducer repository.
Using php compiled with CC=clang and --enable-debug --with-valgrind, instanciating any Reflection object causes valgrind to crash.
Here's an exerpt of the gdb backtrace:
... the rest is just an infinite loop
0x0000000000a00f01 in object_init_ex (arg=0x1ffeffd5b8, class_type=0x4c96f20) at Zend/zend_API.c:1794
0x0000000000b06622 in zend_throw_exception_zstr (exception_ce=0x4c96f20, message=0x4dec7d0, code=0) at Zend/zend_exceptions.c:828
0x0000000000b02b06 in zend_throw_exception (exception_ce=0x4c96f20, message=0x4dec6b0 "Cannot instantiate abstract class Error", code=0) at Zend/zend_exceptions.c:848
0x00000000009f86e6 in zend_throw_error (exception_ce=0x4c96f20, format=0xd569e6 "Cannot instantiate abstract class %s") at Zend/zend.c:1714
0x0000000000a00d6c in _object_and_properties_init (arg=0x1ffeffd888, class_type=0x4c96f20, properties=0x0) at Zend/zend_API.c:1755
0x0000000000a00f01 in object_init_ex (arg=0x1ffeffd5b8, class_type=0x4c96f20) at Zend/zend_API.c:1794
0x0000000000b06622 in zend_throw_exception_zstr (exception_ce=0x4c96f20, message=0x4dec7d0, code=0) at Zend/zend_exceptions.c:828
0x0000000000b02b06 in zend_throw_exception (exception_ce=0x4c96f20, message=0x4dec6b0 "Cannot instantiate abstract class Error", code=0) at Zend/zend_exceptions.c:848
0x00000000009f86e6 in zend_throw_error (exception_ce=0x4c96f20, format=0xd569e6 "Cannot instantiate abstract class %s") at Zend/zend.c:1714
0x0000000000a00d6c in _object_and_properties_init (arg=0x1ffeffd888, class_type=0x4c96f20, properties=0x0) at Zend/zend_API.c:1755
0x0000000000a00f01 in object_init_ex (arg=0x1ffeffd888, class_type=0x4c96f20) at Zend/zend_API.c:1794
0x0000000000b06622 in zend_throw_exception_zstr (exception_ce=0x4c96f20, message=0x4dec630, code=0) at Zend/zend_exceptions.c:828
0x0000000000b02b06 in zend_throw_exception (exception_ce=0x4c96f20, message=0x4dec510 "Cannot instantiate abstract class Error", code=0) at Zend/zend_exceptions.c:848
0x00000000009f86e6 in zend_throw_error (exception_ce=0x4c96f20, format=0xd569e6 "Cannot instantiate abstract class %s") at Zend/zend.c:1714
0x0000000000a00d6c in _object_and_properties_init (arg=0x1ffeffdb58, class_type=0x4c96f20, properties=0x0) at Zend/zend_API.c:1755
0x0000000000a00f01 in object_init_ex (arg=0x1ffeffdb58, class_type=0x4c96f20) at Zend/zend_API.c:1794
0x0000000000b06622 in zend_throw_exception_zstr (exception_ce=0x4c96f20, message=0x4dec490, code=0) at Zend/zend_exceptions.c:828
0x0000000000b02b06 in zend_throw_exception (exception_ce=0x4c96f20, message=0x4dec370 "Class \"ReflectionFunction\" not found", code=0) at Zend/zend_exceptions.c:848
0x00000000009f86e6 in zend_throw_error (exception_ce=0x4c96f20, format=0xd32947 "%s") at Zend/zend.c:1714
0x00000000009dbed6 in zend_throw_or_error (fetch_type=512, exception_ce=0x0, format=0xcb23e2 "Class \"%s\" not found") at Zend/zend_execute_API.c:241
0x00000000009dc00c in report_class_fetch_error (class_name=0x4debdb0, fetch_type=512) at Zend/zend_execute_API.c:1635
0x00000000009dc1fe in zend_fetch_class_by_name (class_name=0x4debdb0, key=0x4debe20, fetch_type=512) at Zend/zend_execute_API.c:1724
0x0000000000a87861 in ZEND_NEW_SPEC_CONST_UNUSED_HANDLER (execute_data=0x4d91300) at Zend/zend_vm_execute.h:10482
0x0000000000a3a049 in execute_ex (ex=0x4d91300) at Zend/zend_vm_execute.h:56856
0x0000000000a3a3da in zend_execute (op_array=0x4deb1f0, return_value=0x0) at Zend/zend_vm_execute.h:61445
0x00000000009f920c in zend_execute_scripts (type=8, retval=0x0, file_count=3) at Zend/zend.c:1864
0x0000000000933561 in php_execute_script (primary_file=0x1fff0008f8) at main/main.c:2482
0x0000000000bc4b33 in do_cli (argc=2, argv=0x4bba7c0) at sapi/cli/php_cli.c:963
0x0000000000bc3cb9 in main (argc=2, argv=0x4bba7c0) at sapi/cli/php_cli.c:1337PHP Version
PHP 8.3-dev
Operating System
Debian bullseye and sid
Reactions are currently unavailable
Activity
ndossche commentedon Jul 16, 2023
First of all, thanks for the nice reproducer!
This seems to happen only under Valgrind, the
--with-valgrindflag also doesn't seem to matter for my setup. Reproduces with a Clang build, works correctly with a GCC build.It infinite loops because it can't seem to find any class at all. i.e. it first wants to throw an exception because it can't find the ReflectionFunction class, then it fails in throwing the exception because it can't find the Error class. It wants to throw that too, so it comes into an infinite loop of wanting to throw an Error because it can't find the Error class.
Indeed, executing this instead of your reproducer:
new Error();, also causes a crash.I also get a bunch of "cannot load module" errors on startup, so that's likely related.
Dumping out the class table shows error is in there, with the right length and hash. Yet zend_hash_find inside zend_lookup_class_ex returns NULL. EDIT: it's zend_string_equal_val that returns 0 in zend_hash_find.
ndossche commentedon Jul 16, 2023
I think this is a Clang bug regarding the Valgrind replacement function. Looking at its disassembly I see a pop rax, so that will overwrite the return value set by the memcmp...
This is a workaround that works for me. I can do a PR later today:
EDIT: and after applying that I get more of those Valgrind splats like in GH-9068 in release mode, haven't investigated why that is yet. In any case, the irony is that our the Valgrind replacement function is the one causing Valgrind to misbehave...
ndossche commentedon Jan 9, 2024
This is also fixed by #13099.