Skip to content

[BUG] 0.29.29 regression: Python memory allocator called without holding the GIL #4796

@pitrou

Description

@pitrou

In PyArrow we have two helper functions looking like this:

cdef int check_status(const CStatus& status) nogil except -1

cdef int plasma_check_status(const CStatus& status) nogil except -1:
    if status.ok():
        return 0

    with gil:
        message = frombytes(status.message())
        if IsPlasmaObjectExists(status):
            raise PlasmaObjectExists(message)
        elif IsPlasmaObjectNotFound(status):
            raise PlasmaObjectNotFound(message)
        elif IsPlasmaStoreFull(status):
            raise PlasmaStoreFull(message)

    return check_status(status)

Starting with 0.29.29, Cython generates an incorrect epilog for plasma_check_status:

  /* "pyarrow/_plasma.pyx":275
 * 
 * 
 * cdef int plasma_check_status(const CStatus& status) nogil except -1:             # <<<<<<<<<<<<<<
 *     if status.ok():
 *         return 0
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  #ifdef WITH_THREAD
  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
  #endif
  __Pyx_AddTraceback("pyarrow._plasma.plasma_check_status", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = -1;
  #ifdef WITH_THREAD
  __Pyx_PyGILState_Release(__pyx_gilstate_save);
  #endif
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_message);
  return __pyx_r;

Notice that __Pyx_XDECREF is called after releasing the GIL.

Here's the diff between 0.29.28 and 0.29.29 generated code:

   /* function exit code */
-  __pyx_r = 0;
-  goto __pyx_L0;
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
+  #ifdef WITH_THREAD
+  __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
+  #endif
   __Pyx_AddTraceback("pyarrow._plasma.plasma_check_status", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_message);
   #ifdef WITH_THREAD
   __Pyx_PyGILState_Release(__pyx_gilstate_save);
   #endif
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_message);
   return __pyx_r;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions