New submission from Mark Dickinson: The argument-passing code for passing structs larger than 8 bytes is broken on 64-bit Windows, leading to potential segmentation faults or other unpredictable behaviour. According to
http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx structs not of size 1, 2, 4 or 8 bytes should be passed by pointer. ctypes instead puts sizeof(struct) bytes onto the stack. The offending code is in ffi_prep_args in /Modules/_ctypes/libffi_msvc/ffi.c, which apparently hasn't been kept up to date with the /Modules/_ctypes/libffi/src/x86/ffi.c. The latter module works correctly: it has an extra #ifdef X86_WIN64 block (shown below) to take care of structs not of size 1, 2, 4 or 8. That block is missing in the libffi_msvc version. z = (*p_arg)->size; #ifdef X86_WIN64 if (z > sizeof(ffi_arg) || ((*p_arg)->type == FFI_TYPE_STRUCT && (z != 1 && z != 2 && z != 4 && z != 8)) #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE) #endif ) { z = sizeof(ffi_arg); *(void **)argp = *p_argv; } else if ((*p_arg)->type == FFI_TYPE_FLOAT) { memcpy(argp, *p_argv, z); } else #endif It looks to me as though issue 17310 may be related. Credit for this discovery should go to Freek Mank. ---------- components: ctypes messages: 207520 nosy: mark.dickinson priority: high severity: normal status: open title: broken ctypes calling convention on MSVC / 64-bit Windows (large structs) type: crash versions: Python 2.7, Python 3.3, Python 3.4 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue20160> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com