On Thu, Nov 13, 2014 at 09:13:11PM +0100, Mike Pall wrote: > It shouldn't. Provide a self-contained example. Thank you so far for taking the time to reply to every message. I spent many hours reducing the application to produce an example, but the more parts are disabled, the less likely it becomes that a cdata object is finalized twice; until the probability of failure becomes so small that I cannot reproduce the error within a reasonable runtime. After some experimentation I found that duplicate finalization occurs only when ffi.gc() is both compiled and invoked in a tail call. This method of constructing objects works fine: ffi.cdef[[typedef struct _cl_event *cl_event;]] local event_ptr = ffi.new("cl_event[1]") local function enqueue_marker(queue) assert(C.CL_SUCCESS == C.clEnqueueMarker(queue, event_ptr)) local event = ffi.gc(event_ptr[0], release_event) -- no tail call return event end This method of constructing objects causes duplicate finalization: local function enqueue_marker(queue) assert(C.CL_SUCCESS == C.clEnqueueMarker(queue, event_ptr)) return ffi.gc(event_ptr[0], release_event) -- tail call end Peter