Title: variadic function call broken on armhf when passing a float argument
Type: Stage: patch review
Components: ctypes Versions: Python 3.11, Python 3.10, Python 3.9, Python 3.8, Python 3.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: FFY00, Nicolas Dessart
Priority: normal Keywords: patch

Created on 2020-02-14 10:03 by Nicolas Dessart, last changed 2021-07-23 09:26 by Nicolas Dessart.

File name Uploaded Description Edit
ctypes_variadic_function_tests.diff Nicolas Dessart, 2020-02-14 10:11 Reproduce this issue with ctypes unit tests on an armhf target.
Pull Requests
URL Status Linked Edit
PR 18560 open Nicolas Dessart, 2020-02-19 13:34
Messages (4)
msg361992 - (view) Author: Nicolas Dessart (Nicolas Dessart) * Date: 2020-02-14 10:03
On armhf and for variadic functions (and contrary to non-variadic functions), the VFP co-processor registers are not used for float argument parameter passing. This specificity is apparently completely disregarded by ctypes which always uses `ffi_prep_cif` to prepare the parameter passing of a function while it should most probably use `ffi_prep_cif_var` for variadic functions.

As such variadic function call with float arguments through ctypes
is currently broken on armhf targets.

I think that ctypes API should be updated to let the user specify if a function is variadic.

I've attached a patch to the ctypes unit tests that I'm using to reproduce this bug.

pi@raspberrypi:~/code/cpython $ ./python -m test test_ctypes    
0:00:00 load avg: 0.00 Run tests sequentially
0:00:00 load avg: 0.00 [1/1] test_ctypes
_testfunc_d_bhilfd_var got 2 3 4 -1242230680 -0.000000 -0.000000
test test_ctypes failed -- Traceback (most recent call last):
  File "/home/pi/code/cpython/Lib/ctypes/test/", line 146, in test_doubleresult_var
    self.assertEqual(result, 21)
AssertionError: -7.086855952261741e-44 != 21

test_ctypes failed

== Tests result: FAILURE ==

1 test failed:

Total duration: 3.8 sec
Tests result: FAILURE
msg362307 - (view) Author: Nicolas Dessart (Nicolas Dessart) * Date: 2020-02-20 10:59
As I said in the associated PR, the build is failing on macOS because ctypes uses an obsolete libffi version bundled into Modules/_ctypes/libffi_osx for this platform. This old version of libffi is missing ffi_prep_cif_var.

There is an open issue that propose to remove the bundled libffi for OSX.
msg398026 - (view) Author: Filipe LaĆ­ns (FFY00) * (Python triager) Date: 2021-07-23 03:06
#28491 is now resolved, so the PR should be unblocked. Would you mind rebasing it on main to retrigger the CI?
msg398040 - (view) Author: Nicolas Dessart (Nicolas Dessart) * Date: 2021-07-23 09:26
I've just rebased this PR but the CI builds failed (for unrelated reasons?).

That being said I think that this particular issue should mostly be resolved by bpo-41100 and PR-22855 in particular. My PR 18560 still brings the support for Ellipsis/... inside ctypes function arguments type list. This is nice because it allows ctypes to automatically perform the necessary type promotions even if a variadic function is called without extra arguments.

Since I've rebased my PR on top of bpo-41100 PRs, I had to resolve a few conflicts but didn't tried to limit the diff to the minimum (PR 18560 may be simplified).
Date User Action Args
2021-07-23 09:26:19Nicolas Dessartsetmessages: + msg398040
versions: + Python 3.10, Python 3.11
2021-07-23 03:06:10FFY00setnosy: + FFY00
messages: + msg398026
2020-02-20 10:59:27Nicolas Dessartsetmessages: + msg362307
versions: - Python 2.7, Python 3.5, Python 3.6
2020-02-19 14:41:18Nicolas Dessartsetversions: + Python 2.7, Python 3.5, Python 3.6, Python 3.7, Python 3.8
2020-02-19 13:34:53Nicolas Dessartsetstage: patch review
pull_requests: + pull_request17940
2020-02-14 10:11:19Nicolas Dessartsetfiles: - ctypes_variadic_function_tests.diff
2020-02-14 10:11:07Nicolas Dessartsetfiles: + ctypes_variadic_function_tests.diff
2020-02-14 10:03:28Nicolas Dessartcreate