ret value must be 10 for strnlen, and 5 for u8_mbsnlen; I've slightly modified the strlen.c from testsuite/libffi.call; in the same manner I've replaced return value type ffi_type_sint with a "structured" type of the size sizeof(size_t). Test interrupts since then: $ ./a.out check new check new->elements check ffi_arg init size of the structure check 1 Aborted All right when return value of ffi_type_sint (comment out rows ##42, 45 and uncomment ##43, 46): $ ./a.out check new check new->elements check ffi_arg init size of the structure check 1 check 7 check 25 There's no problem on x86_64 as well. > tag 593558 + moreinfo > thanks > > On 19.08.2010 10:48, Ygrex wrote: > > Package: libffi-dev > > Version: 3.0.9-2 > > Severity: important > > > > The test C-code is attached: > > gcc-4.4 -lffi -lunistring -o test test.c > > > > It can be compiled without libunistring as well (see notes, please): > > 1. comment out rows #7 and #8 > > 2. uncomment #9 > > 3. gcc-4.4 -lffi -o test test.c > > > > What the code does: > > 1. creates a new ffi_type to emulate size_t; > > 2. allocates array of types of function arguments: (char *) and > > (size_t); 3. prepare CIF to call the size_t function with two > > arguments; 4. allocates array of pointers to two arguments: char *b > > and size_t a; 5. runs ffi_call and segfaults; > > unable to reproduce on i386 unstable (without the library): > > $ valgrind --track-origins=yes -q ./a.out > just before... > ==13621== Conditional jump or move depends on uninitialised value(s) > ==13621== at 0x48DC040: strnlen (mc_replace_strmem.c:263) > ==13621== by 0x48FB54E: ffi_call_SYSV > (in /usr/lib/libffi.so.5.0.10) ==13621== by 0x48FB38D: ffi_call > (in /usr/lib/libffi.so.5.0.10) ==13621== by 0x80488FC: main > (test.c:71) ==13621== Uninitialised value was created by a heap > allocation ==13621== at 0x48DAF50: malloc (vg_replace_malloc.c:236) > ==13621== by 0x8048842: main (test.c:55) > ==13621== > right after! > ==13621== Use of uninitialised value of size 4 > ==13621== at 0x49390FE: _itoa_word (_itoa.c:195) > ==13621== by 0x493C8EF: vfprintf (vfprintf.c:1613) > ==13621== by 0x4943FAF: printf (printf.c:35) > ==13621== by 0x804891F: main (test.c:80) > ==13621== Uninitialised value was created by a heap allocation > ==13621== at 0x48DAF50: malloc (vg_replace_malloc.c:236) > ==13621== by 0x8048842: main (test.c:55) > ==13621== > ==13621== Conditional jump or move depends on uninitialised value(s) > ==13621== at 0x4939106: _itoa_word (_itoa.c:195) > ==13621== by 0x493C8EF: vfprintf (vfprintf.c:1613) > ==13621== by 0x4943FAF: printf (printf.c:35) > ==13621== by 0x804891F: main (test.c:80) > ==13621== Uninitialised value was created by a heap allocation > ==13621== at 0x48DAF50: malloc (vg_replace_malloc.c:236) > ==13621== by 0x8048842: main (test.c:55) > ==13621== > ret value: 0 > -- С уважением, Igor Bogomazov Игорь Богомазов Главный технический специалист HighLink Ltd. St-Petersburg, Russia 8(812)334-12-12 [доб. 220] 8(931)238-94-41 (Мегафон) http://www.hl.ru
#include <stdlib.h> #include <string.h> #include <ffi.h> #define MAX_ARGS 256 #define CHECK(x) !(x) ? abort() : 0 static size_t my_strlen(char *s) { return (strlen(s)); } int main (void) { ffi_type *new = malloc(sizeof(ffi_type)); puts("check new"); CHECK(new); new->size = new->alignment = 0; new->type = FFI_TYPE_STRUCT; new->elements = calloc(5, sizeof(ffi_type *)); puts("check new->elements"); CHECK(new->elements); new->elements[0] = &ffi_type_uchar; new->elements[1] = &ffi_type_uchar; new->elements[2] = &ffi_type_uchar; new->elements[3] = &ffi_type_uchar; new->elements[4] = NULL; ffi_cif cif; ffi_type *args[MAX_ARGS]; void *values[MAX_ARGS]; ffi_arg rint; puts("check ffi_arg"); CHECK(sizeof(ffi_arg) == 4); char *s; args[0] = &ffi_type_pointer; values[0] = (void*) &s; /* Initialize the cif */ puts("init"); CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, new, args) == FFI_OK); // &ffi_type_sint, args) == FFI_OK); puts("size of the structure"); CHECK(new->size == 4); // CHECK(ffi_type_sint.size == 4); s = "a"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); puts("check 1"); CHECK(rint == 1); s = "1234567"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); puts("check 7"); CHECK(rint == 7); s = "1234567890123456789012345"; ffi_call(&cif, FFI_FN(my_strlen), &rint, values); puts("check 25"); CHECK(rint == 25); exit (0); }
Attachment:
signature.asc
Description: PGP signature