You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Crash when returning a 64-bit char pointer in Python 2.6.3 ctypes #51409
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee='https://github.com/theller'closed_at=<Date2009-10-19.14:50:22.603>created_at=<Date2009-10-17.16:31:03.204>labels= ['ctypes', 'type-crash']
title='Crash when returning a 64-bit char pointer in Python 2.6.3 ctypes'updated_at=<Date2009-10-19.14:50:22.602>user='https://bugs.python.org/creachadair'
A segmentation fault is generated in _ctypes.so when calling a function that returns a char pointer on a system
with 64-bit pointer types. The attached crash dump is from a Python 2.6.3 built from MacPorts ("port install
python26 +no_tkinter"), but the same behaviour occurs with the Python 2.6.1 installed by Apple.
To reproduce, build the attached sample program ("testlib.c"):
# Common setup for each of the cases below.
>>> from ctypes import*
>>> lib = CDLL('testlib.so')
# Case 1: Integer return value (no crash).
>>> get_value = CFUNCTYPE(c_int)(lib.get_value)
>>> get_value()
12345
# Case 2: Pointer argument value (no crash).
>>> buf = create_string_buffer(256)
>>> copy_message = CFUNCTYPE(None, c_char_p)(lib.copy_message)
>>> copy_message(buf)
# Case 3: Pointer return value (crash).
>>> get_message = CFUNCTYPE(c_char_p)(lib.get_message)
>>> get_message()
Segmentation fault
-- System information:
% uname -a
MacOS 10.6.1
Darwin gorion.local 10.0.0 Darwin Kernel Version 10.0.0: Fri Jul 31 22:47:34 PDT 2009; root:xnu-
1456.1.25~1/RELEASE_I386 i386
% python
Python 2.6.3 (r263:75183, Oct 17 2009, 01:49:30)
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
I believe this error occurs because a pointer value is being truncated to
32 bits. The exception code is
KERN_INVALID_ADDRESS at 0x00000000002fe020
If you add a diagnostic printout to the body of get_message(), you will
see that its return value is 0x1002fe020, so in other words, the high-
order word 0x00000001 is being discarded somewhere.
Trundle commented on Oct 17, 2009
Trundlemannequin
Mannequin
More actions
You are using CFUNCTYPE wrong. CFUNCTYPE returns a type which will
take a Python function (or an address of a function as integer). You
provide lib.get_message as Python function, which is a wrapper object
for the C function. By default, ctypes assumes an int as return type for
C functions. On your platform, the size of an int is not the same as the
size of a pointer. Therefore, the return value is truncated. You call
the CFUNCTION which then calls lib.get_message which returns the
truncated pointer as integer and then ctypes tries to make a c_char_p
out of the integer which segfaults because it's truncated.
I think what you are really looking for is lib.get_message.restype = c_char_p.
creachadair commented on Oct 19, 2009
creachadairmannequin
MannequinAuthor
More actions
Thank you for setting me straight.
I see now that I misunderstood the scope of CFUNCTYPE, as I was using
it as a general wrapper when in fact it's only needed for callbacks.
Mistakenly, I inferred from reading section 16.15.2.4 of the ctypes
manual [1] that it would be necessary to create prototype wrappers for
calls into the foreign library as well. Obviously that is not the case,
since your described solution works fine.
Activity
creachadair commentedon Oct 17, 2009
A segmentation fault is generated in _ctypes.so when calling a function that returns a char pointer on a system
with 64-bit pointer types. The attached crash dump is from a Python 2.6.3 built from MacPorts ("port install
python26 +no_tkinter"), but the same behaviour occurs with the Python 2.6.1 installed by Apple.
To reproduce, build the attached sample program ("testlib.c"):
% gcc -Wall -c testlib.o
% ld -dylib -o testlib.so testlib.o
Then, in Python:
-- System information:
% uname -a
MacOS 10.6.1
Darwin gorion.local 10.0.0 Darwin Kernel Version 10.0.0: Fri Jul 31 22:47:34 PDT 2009; root:xnu-
1456.1.25~1/RELEASE_I386 i386
% python
Python 2.6.3 (r263:75183, Oct 17 2009, 01:49:30)
[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
% gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)
creachadair commentedon Oct 17, 2009
I believe this error occurs because a pointer value is being truncated to
32 bits. The exception code is
KERN_INVALID_ADDRESS at 0x00000000002fe020
If you add a diagnostic printout to the body of get_message(), you will
see that its return value is 0x1002fe020, so in other words, the high-
order word 0x00000001 is being discarded somewhere.
Trundle commentedon Oct 17, 2009
You are using
CFUNCTYPEwrong.CFUNCTYPEreturns a type which willtake a Python function (or an address of a function as integer). You
provide
lib.get_messageas Python function, which is a wrapper objectfor the C function. By default, ctypes assumes an int as return type for
C functions. On your platform, the size of an int is not the same as the
size of a pointer. Therefore, the return value is truncated. You call
the CFUNCTION which then calls
lib.get_messagewhich returns thetruncated pointer as integer and then ctypes tries to make a
c_char_pout of the integer which segfaults because it's truncated.
I think what you are really looking for is
lib.get_message.restype = c_char_p.creachadair commentedon Oct 19, 2009
Thank you for setting me straight.
I see now that I misunderstood the scope of
CFUNCTYPE, as I was usingit as a general wrapper when in fact it's only needed for callbacks.
Mistakenly, I inferred from reading section 16.15.2.4 of the ctypes
manual [1] that it would be necessary to create prototype wrappers for
calls into the foreign library as well. Obviously that is not the case,
since your described solution works fine.
[1] <http://www.python.org/doc/2.6.3/library/ctypes.html#function-
prototypes>