Our support of passing structs and unions by value is really bad. Passing this particular struct by value is also broken on 64-bit Unix, but instead because it's small. It crashes Python due to an abort(). See issue 22273.

Just trying to confirm my understanding - in both this issue and #22273, the example struct has a single array member. Is the problem confined just to how ctypes describes arrays in structs/unions to libffi? The comment on #22273 seems to suggest so.

The contents of the struct is just being big enough to reach the point where it is passed by reference rather than by value.
This issue is pointing out that it should be a reference to a temporary copy of the struct, so that if the called function modifies the argument then it doesn't affect the caller.

This issue is more straight-forward than #22273. ISTM, we just have to copy large values. For example, in ffi_call, we'd iterate over the arguments and alloca and memcpy the large values prior to calling ffi_call_AMD64:
case FFI_SYSV:
/* If a single argument takes more than 8 bytes,
then a copy is passed by reference. */
for (unsigned i = 0; i < cif->nargs; i++) {
size_t z = cif->arg_types[i]->size;
if (z > 8) {
void *temp = alloca(z);
memcpy(temp, avalue[i], z);
avalue[i] = temp;
}
}
/*@-usedef@*/
return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;

New test causes a compiler warning:
/home/serhiy/py/cpython/Modules/_ctypes/_ctypes_test.c: In function ‘_testfunc_large_struct_update_value’:
/home/serhiy/py/cpython/Modules/_ctypes/_ctypes_test.c:53:42: warning: parameter ‘in’ set but not used [-Wunused-but-set-parameter]
_testfunc_large_struct_update_value(Test in)
^
Could it be silenced?