Skip to content

Commit c4ce239

Browse files
committed
Detected memory leak in python loader.
1 parent 0363f9c commit c4ce239

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

source/loaders/py_loader/source/py_loader_impl.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,15 @@ static char *py_loader_impl_main_module = NULL;
227227

228228
void py_loader_impl_value_invoke_state_finalize(value v, void *data)
229229
{
230-
loader_impl_py_function_type_invoke_state invoke_state = (loader_impl_py_function_type_invoke_state)data;
230+
PyObject *capsule = (PyObject *)data;
231+
232+
loader_impl_py_function_type_invoke_state invoke_state = (loader_impl_py_function_type_invoke_state)PyCapsule_GetPointer(capsule, NULL);
231233

232234
(void)v;
233235

234236
free(invoke_state);
237+
238+
Py_XDECREF(capsule);
235239
}
236240

237241
void py_loader_impl_value_ptr_finalize(value v, void *data)
@@ -1286,15 +1290,19 @@ PyObject *py_loader_impl_value_to_capi(loader_impl impl, type_id id, value v)
12861290

12871291
invoke_state->impl = impl;
12881292
invoke_state->py_impl = loader_impl_get(impl);
1289-
invoke_state->callback = value_type_copy(v);
12901293

1291-
/* Set up finalizer in order to free the invoke state */
1292-
value_finalizer(invoke_state->callback, &py_loader_impl_value_invoke_state_finalize, invoke_state);
1294+
/* TODO: This line causes a memory leak because the function copy is never destroyed.
1295+
We should add a tp_finalizer field into the returned PyCFunction in order to execute
1296+
a callback where value_type_destroy is executed against invoke_state->callback */
1297+
invoke_state->callback = value_type_copy(v);
12931298

12941299
invoke_state_capsule = PyCapsule_New(invoke_state, NULL, NULL);
12951300

12961301
Py_XINCREF(invoke_state_capsule);
12971302

1303+
/* Set up finalizer in order to free the invoke state */
1304+
value_finalizer(invoke_state->callback, &py_loader_impl_value_invoke_state_finalize, invoke_state_capsule);
1305+
12981306
return PyCFunction_New(py_loader_impl_function_type_invoke_defs, invoke_state_capsule);
12991307
}
13001308
else if (id == TYPE_NULL)

0 commit comments

Comments
 (0)