cdata finalizer called twice

  • From: Peter Colberg <peter@xxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 12 Nov 2014 23:14:29 -0500

Hi Mike,

I am tracing a possible bug in the LuaJIT 2.0 branch where a cdata
finalizer is called twice for the same object. The cdata type is an
incomplete struct defined as

  ffi.cdef[[
  typedef struct _cl_event *cl_event;
  ]]

and the cdata objects are constructed using a function similar to

  ffi.cdef[[
  cl_int clEnqueueMarker(cl_command_queue, cl_event *);
  cl_int clReleaseEvent(cl_event);
  ]]

  local function release_event(event)
    local status = C.clReleaseEvent(event)
    if status ~= C.CL_SUCCESS then
      io.write("DUPLICATE clReleaseEvent("..tostring(event)..")\n")
      return error(errors[status]) -- Invalid event
    end
    io.write("clReleaseEvent("..tostring(event)..")\n")
  end

  local cl_event_1 = ffi.typeof("cl_event[1]")

  local function enqueue_marker(queue)
    local event = cl_event_1()
    local status = C.clEnqueueMarker(queue, event)
    if status ~= C.CL_SUCCESS then return error(errors[status]) end
    return ffi.gc(event[0], release_event)
  end

When I run »10000 iterations of creating and destroying cl_event
objects, forcing immediate destruction through collectgarbage(),
LuaJIT will for most runs (but not always) eventually call the
finalizer of a few of these objects twice:

  …
  clReleaseEvent(cdata<struct _cl_event *>: 0x038fd658)
  clReleaseEvent(cdata<struct _cl_event *>: 0x037bb198)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038f9b28)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03ba0a88)
  clReleaseEvent(cdata<struct _cl_event *>: 0x00960b48)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bcad48)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bca4b8)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bca168)               <---
  DUPLICATE clReleaseEvent(cdata<struct _cl_event *>: 0x03bca168)     <--!
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc9e08)               <---
  DUPLICATE clReleaseEvent(cdata<struct _cl_event *>: 0x03bc9e08)     <--!
  /theory2/u4/pcolberg/vcs/git/luajit-2.0/src/luajit: Invalid event
  clReleaseEvent(cdata<struct _cl_event *>: 0x03ba0448)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03ba1268)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038fd5e8)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038fb678)
  clReleaseEvent(cdata<struct _cl_event *>: 0x00960b48)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038fb888)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc8998)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc8068)
  clReleaseEvent(cdata<struct _cl_event *>: 0x039e6678)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038f9b28)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc8ed8)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03814988)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038fbdb8)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc9748)
  clReleaseEvent(cdata<struct _cl_event *>: 0x038f2068)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03bc9aa8)
  clReleaseEvent(cdata<struct _cl_event *>: 0x03ba0658)
  clReleaseEvent(cdata<struct _cl_event *>: 0x039e6b08)
  Segmentation fault (core dumped)

Using git bisect I identified this commit as causing the issue:

  commit 0b55e05d06bc760070b8ca9f99c01c3d8e67e7db
  Author: Mike Pall <mike>
  Date:   Wed Oct 10 18:56:16 2012 +0200

      FFI: Compile ffi.gc().

Hopefully the above information provides sufficient hints, since so
far I could not produce a self-contained minimal example.

Thanks,
Peter

Other related posts: