[pypy-issue] [issue1593] segfault with ctypes callback on OS X

Florian Schulze tracker at bugs.pypy.org
Sun Sep 1 10:55:29 CEST 2013

New submission from Florian Schulze <florian.schulze at gmx.net>:

When I run the code below I consistently get a segfault a few seconds after touching the 
trackpad with several fingers. Even if I do nothing inside the callback except "return 0" I get 
the segfault.

It seems like MTDeviceStart spawns a new thread in which the callback is called.

It works fine with Python 2.7.5.

import time
import ctypes
import threading

CFArrayRef = ctypes.c_void_p
CFMutableArrayRef = ctypes.c_void_p
CFIndex = ctypes.c_long

MultitouchSupport = 

CFArrayGetCount = MultitouchSupport.CFArrayGetCount
CFArrayGetCount.argtypes = [CFArrayRef]
CFArrayGetCount.restype = CFIndex

CFArrayGetValueAtIndex = MultitouchSupport.CFArrayGetValueAtIndex
CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
CFArrayGetValueAtIndex.restype = ctypes.c_void_p

MTDeviceCreateList = MultitouchSupport.MTDeviceCreateList
MTDeviceCreateList.argtypes = []
MTDeviceCreateList.restype = CFMutableArrayRef

class MTPoint(ctypes.Structure):
    _fields_ = [("x", ctypes.c_float),
                ("y", ctypes.c_float)]

class MTVector(ctypes.Structure):
    _fields_ = [("position", MTPoint),
                ("velocity", MTPoint)]

class MTData(ctypes.Structure):
    _fields_ = [
      ("frame", ctypes.c_int),
      ("timestamp", ctypes.c_double),
      ("identifier", ctypes.c_int),
      ("state", ctypes.c_int),  # Current state (of unknown meaning).
      ("unknown1", ctypes.c_int),
      ("unknown2", ctypes.c_int),
      ("normalized", MTVector),  # Normalized position and vector of
                                 # the touch (0 to 1).
      ("size", ctypes.c_float),  # The area of the touch.
      ("unknown3", ctypes.c_int),
      # The following three define the ellipsoid of a finger.
      ("angle", ctypes.c_float),
      ("major_axis", ctypes.c_float),
      ("minor_axis", ctypes.c_float),
      ("unknown4", MTVector),
      ("unknown5_1", ctypes.c_int),
      ("unknown5_2", ctypes.c_int),
      ("unknown6", ctypes.c_float),

MTDataRef = ctypes.POINTER(MTData)

MTContactCallbackFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, MTDataRef,
    ctypes.c_int, ctypes.c_double, ctypes.c_int)

MTDeviceRef = ctypes.c_void_p

MTRegisterContactFrameCallback = MultitouchSupport.MTRegisterContactFrameCallback
MTRegisterContactFrameCallback.argtypes = [MTDeviceRef, MTContactCallbackFunction]
MTRegisterContactFrameCallback.restype = None

MTDeviceStart = MultitouchSupport.MTDeviceStart
MTDeviceStart.argtypes = [MTDeviceRef, ctypes.c_int]
MTDeviceStart.restype = None


def my_callback(device, data_ptr, n_fingers, timestamp, frame):
    print threading.current_thread(), device, data_ptr, n_fingers, timestamp, frame
    for i in xrange(n_fingers):
        data = data_ptr[i]
        d = "x=%.2f, y=%.2f" % (data.normalized.position.x * 100,
                                data.normalized.position.y * 100)
        print "%d: %s" % (i, d)
    return 0

devices = MultitouchSupport.MTDeviceCreateList()
num_devices = CFArrayGetCount(devices)
print "num_devices =", num_devices
for i in xrange(num_devices):
    device = CFArrayGetValueAtIndex(devices, i)
    print "device #%d: %016x" % (i, device)
    MTRegisterContactFrameCallback(device, my_callback)
    MTDeviceStart(device, 0)

print threading.current_thread()

while threading.active_count():
    # Why sleep instead of join? Ask David Beazley.

messages: 6107
nosy: fschulze, pypy-issue
priority: bug
status: unread
title: segfault with ctypes callback on OS X

PyPy bug tracker <tracker at bugs.pypy.org>

More information about the pypy-issue mailing list