Skip to content

Commit 66bed1d

Browse files
Fix refleaks.
1 parent c25d9e1 commit 66bed1d

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

Include/internal/pycore_crossinterp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ typedef struct {
354354
PyObject *preserved;
355355
PyObject *excinfo;
356356
} _PyXI_session_result;
357+
PyAPI_FUNC(void) _PyXI_ClearResult(_PyXI_session_result *);
357358

358359
PyAPI_FUNC(int) _PyXI_Enter(
359360
_PyXI_session *session,

Modules/_interpretersmodule.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -436,17 +436,16 @@ struct interp_call {
436436
static void
437437
_interp_call_clear(struct interp_call *call)
438438
{
439-
struct interp_call temp = *call;
440-
*call = (struct interp_call){0};
441-
if (temp.func != NULL) {
442-
_PyXIData_Clear(NULL, temp.func);
439+
if (call->func != NULL) {
440+
_PyXIData_Clear(NULL, call->func);
443441
}
444-
if (temp.args != NULL) {
445-
_PyXIData_Clear(NULL, temp.args);
442+
if (call->args != NULL) {
443+
_PyXIData_Clear(NULL, call->args);
446444
}
447-
if (temp.kwargs != NULL) {
448-
_PyXIData_Clear(NULL, temp.kwargs);
445+
if (call->kwargs != NULL) {
446+
_PyXIData_Clear(NULL, call->kwargs);
449447
}
448+
*call = (struct interp_call){0};
450449
}
451450

452451
static int
@@ -467,9 +466,9 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
467466
PyObject *exc = _PyErr_GetRaisedException(tstate);
468467
if (_PyPickle_GetXIData(tstate, func, &call->_preallocated.func) < 0) {
469468
_PyErr_SetRaisedException(tstate, exc);
470-
//unwrap_not_shareable(tstate);
471469
return -1;
472470
}
471+
Py_DECREF(exc);
473472
}
474473
call->func = &call->_preallocated.func;
475474
// Handle the args.
@@ -482,6 +481,7 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
482481
if (_PyObject_GetXIData(
483482
tstate, args, fallback, &call->_preallocated.args) < 0)
484483
{
484+
_interp_call_clear(call);
485485
return -1;
486486
}
487487
call->args = &call->_preallocated.args;
@@ -497,6 +497,7 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
497497
if (_PyObject_GetXIData(
498498
tstate, kwargs, fallback, &call->_preallocated.kwargs) < 0)
499499
{
500+
_interp_call_clear(call);
500501
return -1;
501502
}
502503
call->kwargs = &call->_preallocated.kwargs;
@@ -648,11 +649,11 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
648649
(void)_PyXI_Exit(session, &result);
649650
_PyXI_FreeSession(session);
650651
if (res < 0) {
651-
runres->excinfo = result.excinfo;
652+
runres->excinfo = Py_NewRef(result.excinfo);
652653
runres->badtarget = badtarget;
653654
}
654655
else if (result.excinfo != NULL) {
655-
runres->excinfo = result.excinfo;
656+
runres->excinfo = Py_NewRef(result.excinfo);
656657
runres->badtarget = badtarget;
657658
res = -1;
658659
}
@@ -662,6 +663,7 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
662663
res = -1;
663664
}
664665
}
666+
_PyXI_ClearResult(&result);
665667
return res;
666668
}
667669

@@ -1276,12 +1278,16 @@ handle_call_error(struct interp_call *call, struct run_result *runres)
12761278
return 0;
12771279
}
12781280

1281+
// Handle the case where _PyXIData_NewObject() fails.
12791282
PyObject *func, *args, *kwargs;
12801283
if (_interp_call_unpack(call, &func, &args, &kwargs) == 0) {
12811284
// Either the problem is intermittent or only affects subinterpreters.
12821285
// This is highly unlikely.
12831286
return 0;
12841287
}
1288+
Py_DECREF(func);
1289+
Py_XDECREF(args);
1290+
Py_XDECREF(kwargs);
12851291
assert(PyErr_Occurred());
12861292
PyThreadState *tstate = _PyThreadState_GET();
12871293
unwrap_not_shareable(tstate);

Python/crossinterp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,6 +2765,13 @@ _PyXI_GetPreserved(_PyXI_session_result *result, const char *name)
27652765
return value;
27662766
}
27672767

2768+
void
2769+
_PyXI_ClearResult(_PyXI_session_result *result)
2770+
{
2771+
Py_CLEAR(result->preserved);
2772+
Py_CLEAR(result->excinfo);
2773+
}
2774+
27682775

27692776
/*********************/
27702777
/* runtime lifecycle */

0 commit comments

Comments
 (0)