This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author T.Rex
Recipients Ayappan, BTaskaya, David.Edelsohn, Michael.Felt, T.Rex, amaury.forgeotdarc, belopolsky, meador.inge, ronaldoussoren
Date 2020-08-03.09:48:24
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1596448105.23.0.214850016631.issue38628@roundup.psfhosted.org>
In-reply-to
Content
After more investigations, we (Damien and I) think that there are several issues in Python 3.8.5 :

1) Documentation.
  a) AFAIK, the only place in the Python ctypes documentation where it talks about how arrays in a structure are managed appears at: https://docs.python.org/3/library/ctypes.html#arrays
  b) the size of the structure in the example given here is much greater than in our case.
  c) The documentation does NOT talk that a structure <= 16 bytes and a structure greater than 16 bytes are managed differently. That's a bug in the documentation vs the code.

2) Tests
  Looking at tests, there are NO test about our case.

3) There is a bug in Python
  About the issue here, we see with gdb that Python provides libffi with a description saying that our case is passed as pointers. However, Python does NOT provides libffi with pointers for the array c_n, but with values.

4) libffi obeys Python directives given in description, thinking that it deals with 2 pointers, and thus it pushes only 2 values in registers R3 and R4.

=====================================================
Bug in Python:
-----------------------------------------------------
1) gdb
(gdb) b ffi_call

Breakpoint 1 at 0x9000000016fab80: file ../src/powerpc/ffi_darwin.c, line 919.

(gdb) run

Starting program: /home2/freeware/bin/python3 /tmp/Pb_damien2.py

Thread 2 hit Breakpoint 1, ffi_call (cif=0xfffffffffffd108,

    fn=@0x9001000a0082640: 0x9000000001b0d60 <memchr>,

    rvalue=0xfffffffffffd1d0, avalue=0xfffffffffffd1c0)

(gdb) p *(ffi_cif *)$r3

$9 = {abi = FFI_AIX, nargs = 2, arg_types = 0xfffffffffffd1b0, rtype = 0xa00000000435cb8, bytes = 144, flags = 8}

(gdb) x/2xg 0xfffffffffffd1b0

0xfffffffffffd1b0:      0x0a0000000043ca48      0x08001000a0002a10

(gdb) p *(ffi_type *)0x0a0000000043ca48

$11 = {size = 16, alignment = 8, type = 13, elements = 0xa0000000012eed0}   <= 13==FFI_TYPE_STRUCT size == 16 on AIX!!! == 24 on Linux

(gdb) p *(ffi_type *)0x08001000a0002a10

$12 = {size = 8, alignment = 8, type = 14, elements = 0x0} <= FFI_TYPE_POINTER


(gdb) x/3xg *(long *)$r6

0xa00000000436050:      0x0a00000000152200      0x0000000000000064

0xa00000000436060:      0x0000000000000007  <= 7 is present in avalue[2]

(gdb) x/s 0x0a00000000152200

0xa00000000152200:      "abcdef"

-----------------------------------------------------
2) prints in libffi: AIX : aix_adjust_aggregate_sizes()

TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() s->size: 8 s->type:14 : FFI_TYPE_POINTER
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() s->size:24 s->type:13 : FFI_TYPE_STRUCT
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() FFI_TYPE_STRUCT Before s->size:24
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() s->size: 8 s->type:14 : FFI_TYPE_POINTER
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() p->size: 8 s->size: 8
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() s->size: 8 s->type:14 : FFI_TYPE_POINTER
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() p->size: 8 s->size:16
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() After ALIGN s->size:16
TONY: libffi: src/powerpc/ffi_darwin.c : aix_adjust_aggregate_sizes() s->size: 8 s->type:14 : FFI_TYPE_POINTER
TONY: libffi: src/powerpc/ffi_darwin.c: ffi_call: FFI_AIX
TONY: libffi: cif->abi:  1  -(long)cif->bytes : -144  cif->flags :  8  ecif.rvalue : fffffffffffd200  fn: 9001000a0227760  FFI_FN(ffi_prep_args) : 9001000a050a108
s   element  : char pointer: a00000000153d40 abcdef
c_n element 0: a Long:       100          0X64 = 100  instead of a pointer
c_n element 1: a Long:       0      libffi obeys description given by Python and pushes to R4 only what it thinks is a pointer (100 instead), and nothing in R5

====================================================================

Summary:
- Python documentation is uncomplete vs the code
- Python code gives libffi a description about pointers
  but Python code provides libffi with values.
History
Date User Action Args
2020-08-03 09:48:25T.Rexsetrecipients: + T.Rex, ronaldoussoren, amaury.forgeotdarc, belopolsky, meador.inge, David.Edelsohn, Michael.Felt, Ayappan, BTaskaya
2020-08-03 09:48:25T.Rexsetmessageid: <1596448105.23.0.214850016631.issue38628@roundup.psfhosted.org>
2020-08-03 09:48:25T.Rexlinkissue38628 messages
2020-08-03 09:48:24T.Rexcreate