Message207520
| Author |
mark.dickinson |
| Recipients |
mark.dickinson |
| Date |
2014年01月07日.09:37:53 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1389087474.06.0.281853443562.issue20160@psf.upfronthosting.co.za> |
| In-reply-to |
| Content |
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. |
|
History
|
|---|
| Date |
User |
Action |
Args |
| 2014年01月07日 09:37:54 | mark.dickinson | set | recipients:
+ mark.dickinson |
| 2014年01月07日 09:37:54 | mark.dickinson | set | messageid: <1389087474.06.0.281853443562.issue20160@psf.upfronthosting.co.za> |
| 2014年01月07日 09:37:54 | mark.dickinson | link | issue20160 messages |
| 2014年01月07日 09:37:53 | mark.dickinson | create |
|