Open
Description
Description
The following code:
<?php
class MyClass
{
public static function do(): void
{
$ffi = FFI::cdef("struct struct1{int x;};struct struct2{int y;};void takesStruct1(struct struct1*);", __DIR__ . "/a.out");
$struct2 = $ffi->new("struct struct2");
$ffi->takesStruct1(FFI::addr($struct2));
}
}
MyClass::do();
With the following C source for a.out (compile with cc -shared test.c
):
#include <stdio.h>
struct struct1{int x; int y;};
struct struct2{int x;};
void takesStruct1(struct struct1*){printf("I took a struct1!");}
Resulted in this output:
php: /home/iggyvolz/php-src/ext/ffi/ffi.c:1631: zend_ffi_ctype_name: Assertion `0' failed.
Aborted
With the following gdb backtrace:
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)
at ./nptl/pthread_kill.c:44
#1 0x00007ffff6bfcd9f in __pthread_kill_internal (signo=6, threadid=<optimized out>)
at ./nptl/pthread_kill.c:78
#2 0x00007ffff6badf32 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff6b98472 in __GI_abort () at ./stdlib/abort.c:79
#4 0x00007ffff6b98395 in __assert_fail_base (
fmt=0x7ffff6d0ca90 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x555555e9582e "0",
file=file@entry=0x555555e95188 "/home/iggyvolz/php-src/ext/ffi/ffi.c", line=line@entry=1631,
function=function@entry=0x555555e97ca0 <__PRETTY_FUNCTION__.58> "zend_ffi_ctype_name")
at ./assert/assert.c:92
#5 0x00007ffff6ba6e32 in __GI___assert_fail (assertion=0x555555e9582e "0",
file=0x555555e95188 "/home/iggyvolz/php-src/ext/ffi/ffi.c", line=1631,
function=0x555555e97ca0 <__PRETTY_FUNCTION__.58> "zend_ffi_ctype_name") at ./assert/assert.c:101
#6 0x0000555555779388 in zend_ffi_ctype_name (buf=0x7fffffffa4e0, type=0x7ffff407f080)
at /home/iggyvolz/php-src/ext/ffi/ffi.c:1631
#7 0x0000555555779932 in zend_ffi_get_class_name (prefix=0x555556dc1ad0, type=0x7ffff407f300)
at /home/iggyvolz/php-src/ext/ffi/ffi.c:1732
#8 0x00005555557799d1 in zend_ffi_cdata_get_class_name (zobj=0x7ffff407f380)
at /home/iggyvolz/php-src/ext/ffi/ffi.c:1745
#9 0x0000555555cfaaee in _build_trace_args (arg=0x7ffff40603c8, str=0x7fffffffa720)
at /home/iggyvolz/php-src/Zend/zend_exceptions.c:517
#10 0x0000555555cfb06d in _build_trace_string (str=0x7fffffffa720, ht=0x7ffff405c6c0, num=0)
at /home/iggyvolz/php-src/Zend/zend_exceptions.c:576
#11 0x0000555555cfb235 in zend_trace_to_string (trace=0x7ffff405c660, include_main=true)
at /home/iggyvolz/php-src/Zend/zend_exceptions.c:602
#12 0x0000555555cfb3e8 in zim_Exception_getTraceAsString (execute_data=0x7ffff4016070,
return_value=0x7fffffffaa90) at /home/iggyvolz/php-src/Zend/zend_exceptions.c:631
#13 0x0000555555c07d8c in zend_call_function (fci=0x7fffffffaa50, fci_cache=0x7fffffffa830)
at /home/iggyvolz/php-src/Zend/zend_execute_API.c:970
#14 0x0000555555cfb6da in zim_Exception___toString (execute_data=0x7ffff4016020,
return_value=0x7fffffffaed0) at /home/iggyvolz/php-src/Zend/zend_exceptions.c:676
#15 0x0000555555c07d8c in zend_call_function (fci=0x7fffffffadc0, fci_cache=0x7fffffffad90)
at /home/iggyvolz/php-src/Zend/zend_execute_API.c:970
#16 0x0000555555c0826a in zend_call_known_function (fn=0x555556d33960, object=0x7ffff4060300,
called_scope=0x555556dc0170, retval_ptr=0x7fffffffaed0, param_count=0, params=0x0, named_params=0x0)
at /home/iggyvolz/php-src/Zend/zend_execute_API.c:1051
#17 0x0000555555cf7b95 in zend_call_known_instance_method (fn=0x555556d33960, object=0x7ffff4060300,
retval_ptr=0x7fffffffaed0, param_count=0, params=0x0) at /home/iggyvolz/php-src/Zend/zend_API.h:853
#18 0x0000555555cf7bcf in zend_call_known_instance_method_with_0_params (fn=0x555556d33960,
object=0x7ffff4060300, retval_ptr=0x7fffffffaed0) at /home/iggyvolz/php-src/Zend/zend_API.h:859
#19 0x0000555555cfc8c0 in zend_exception_error (ex=0x7ffff4060300, severity=1)
at /home/iggyvolz/php-src/Zend/zend_exceptions.c:921
#20 0x0000555555c243e1 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /home/iggyvolz/php-src/Zend/zend.c:1888
#21 0x0000555555b61ee2 in php_execute_script (primary_file=0x7fffffffd4f0)
at /home/iggyvolz/php-src/main/main.c:2501
#22 0x0000555555dae79d in do_cli (argc=2, argv=0x555556c29550)
at /home/iggyvolz/php-src/sapi/cli/php_cli.c:966
#23 0x0000555555daf56f in main (argc=2, argv=0x555556c29550)
at /home/iggyvolz/php-src/sapi/cli/php_cli.c:1340
But when I run with this (should-be-equivalent) PHP code:
<?php
$ffi = FFI::cdef("struct struct1{int x;};struct struct2{int y;};void takesStruct1(struct struct1*);", __DIR__ . "/a.out");
$struct2 = $ffi->new("struct struct2");
$ffi->takesStruct1(FFI::addr($struct2));
I receive the correct output:
Fatal error: Uncaught FFI\Exception: Passing incompatible argument 1 of C function 'takesStruct1', expecting 'struct struct1*', found 'struct struct2*' in /home/iggyvolz/phpwayland/testsegfault.php:17
Stack trace:
#0 /.../testsegfault.php(17): FFI->takesStruct1(Object(FFI\CData:struct struct2*))
#1 {main}
thrown in /home/iggyvolz/phpwayland/testsegfault.php on line 17
While debugging this issue, I also found a similar-seeming issue with the following class:
<?php
FFI::cdef("void FAKE_FUNCTION();");
Returns a memory leak in the debug build of PHP:
Fatal error: Uncaught FFI\Exception: Failed resolving C function 'FAKE_FUNCTION' in /home/iggyvolz/phpwayland/testmemleak.php:2
Stack trace:
#0 /home/iggyvolz/phpwayland/testmemleak.php(2): FFI::cdef('void FAKE_FUNCT...')
#1 {main}
thrown in /home/iggyvolz/phpwayland/testmemleak.php on line 2
[Fri Dec 8 07:48:04 2023] Script: '/home/iggyvolz/phpwayland/testmemleak.php'
/home/iggyvolz/php-src/Zend/zend_string.h(174) : Freeing 0x00007f7aece02dc0 (40 bytes), script=/home/iggyvolz/phpwayland/testmemleak.php
[Fri Dec 8 07:48:04 2023] Script: '/home/iggyvolz/phpwayland/testmemleak.php'
/home/iggyvolz/php-src/ext/ffi/ffi.c(6628) : Freeing 0x00007f7aece5b118 (24 bytes), script=/home/iggyvolz/phpwayland/testmemleak.php
[Fri Dec 8 07:48:04 2023] Script: '/home/iggyvolz/phpwayland/testmemleak.php'
/home/iggyvolz/php-src/ext/ffi/ffi.c(6559) : Freeing 0x00007f7aece5c540 (56 bytes), script=/home/iggyvolz/phpwayland/testmemleak.php
[Fri Dec 8 07:48:04 2023] Script: '/home/iggyvolz/phpwayland/testmemleak.php'
/home/iggyvolz/php-src/Zend/zend_hash.c(177) : Freeing 0x00007f7aece6c300 (320 bytes), script=/home/iggyvolz/phpwayland/testmemleak.php
[Fri Dec 8 07:48:04 2023] Script: '/home/iggyvolz/phpwayland/testmemleak.php'
/home/iggyvolz/php-src/ext/ffi/ffi.c(6440) : Freeing 0x00007f7aece7e000 (88 bytes), script=/home/iggyvolz/phpwayland/testmemleak.php
=== Total 5 memory leaks detected ===
Not sure whether this is a different bug or just the same underlying issue manifesting differently, but they feel similar enough that my suspicion is the latter (I can split this into a separate issue if requested).
PHP Version
PHP 8.3.0
Operating System
Debian 12