Closed mikhainin closed 1 year ago
Basically, not modification of the array is even enforced: when PHP is built with --enable-debug
(checked on PHP 8.0.28
)
lldb -- /opt/phpbuild/bin/php -n -c '/Users/mikhailgalanin/repos/php-build/github.com-alexeyrybak-blitz/tmp-php.ini' -d "output_handler=" -d "open_basedir=" -d "disable_functions=" -d "output_buffering=Off" -d "error_reporting=32767" -d "display_errors=1" -d "display_startup_errors=1" -d "log_errors=0" -d "html_errors=0" -d "track_errors=0" -d "report_memleaks=1" -d "report_zend_debug=0" -d "docref_root=" -d "docref_ext=.html" -d "error_prepend_string=" -d "error_append_string=" -d "auto_prepend_file=" -d "auto_append_file=" -d "ignore_repeated_errors=0" -d "precision=14" -d "serialize_precision=-1" -d "memory_limit=128M" -d "opcache.fast_shutdown=0" -d "opcache.file_update_protection=0" -d "opcache.revalidate_freq=0" -d "opcache.jit_hot_loop=1" -d "opcache.jit_hot_func=1" -d "opcache.jit_hot_return=1" -d "opcache.jit_hot_side_exit=1" -d "zend.assertions=1" -d "zend.exception_ignore_args=0" -d "zend.exception_string_param_max_len=15" -d "short_open_tag=0" -d "extension_dir=/Users/mikhailgalanin/repos/php-build/github.com-alexeyrybak-blitz/modules/" -d "extension=blitz.so" -d "session.auto_start=0" -d "zlib.output_compression=Off" -f "/Users/mikhailgalanin/repos/php-build/github.com-alexeyrybak-blitz/tests/arithmetics.php"
Process 69528 launched: '/opt/phpbuild/bin/php' (arm64)
Assertion failed: ((&ht->nInternalPointer != pos || zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))), function zend_hash_internal_pointer_reset_ex, file zend_hash.c, line 2305.
Process 69528 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert
frame #4: 0x00000001004b0644 php`zend_hash_internal_pointer_reset_ex(ht=0x000000010164d900, pos=0x000000010164d924) at zend_hash.c:2305:2
2302 ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
2303 {
2304 IS_CONSISTENT(ht);
-> 2305 HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
2306 *pos = _zend_hash_get_valid_pos(ht, 0);
2307 }
2308
* thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert
frame #0: 0x00000001944f2868 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x0000000194529cec libsystem_pthread.dylib`pthread_kill + 288
frame #2: 0x00000001944622c8 libsystem_c.dylib`abort + 180
frame #3: 0x0000000194461620 libsystem_c.dylib`__assert_rtn + 272
* frame #4: 0x00000001004b0644 php`zend_hash_internal_pointer_reset_ex(ht=0x000000010164d900, pos=0x000000010164d924) at zend_hash.c:2305:2
frame #5: 0x00000001011c6e14 blitz.so`blitz_merge_iterations_set(tpl=0x0000000101679000, input_arr=0x0000000101609160) at blitz.c:5067:5
frame #6: 0x00000001011ba01c blitz.so`zif_blitz_display(execute_data=0x0000000101609110, return_value=0x000000016fdfd1e0) at blitz.c:5466:14
frame #7: 0x0000000100507628 php`ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(execute_data=0x0000000101609020) at zend_vm_execute.h:1755:4
frame #8: 0x00000001004c8788 php`execute_ex(ex=0x0000000101609020) at zend_vm_execute.h:54970:7
frame #9: 0x00000001004c8a5c php`zend_execute(op_array=0x0000000101652280, return_value=0x0000000000000000) at zend_vm_execute.h:59523:2
frame #10: 0x0000000100494790 php`zend_execute_scripts(type=8, retval=0x0000000000000000, file_count=3) at zend.c:1826:4
frame #11: 0x00000001003e64ac php`php_execute_script(primary_file=0x000000016fdfdcf0) at main.c:2568:13
frame #12: 0x00000001005b74f4 php`do_cli(argc=80, argv=0x0000000101508430) at php_cli.c:949:5
frame #13: 0x00000001005b6804 php`main(argc=80, argv=0x0000000101508430) at php_cli.c:1341:18
frame #14: 0x00000001941ffe50 dyld`start + 2544
Array functions by default mutate the state of the array (internal pointer), which is supposedly not what the user would expect.
Updated implementation to use *_ex() functions that introduce their own state and not create a copy of the array