From c9b446f7c59507d1d6e09597d127d48dd0a12c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Sat, 24 Sep 2022 13:38:33 +0700 Subject: [PATCH] renderdoc: fix memleak with Python 3.11 --- srcpkgs/renderdoc/patches/python-3.11.patch | 104 ++++++++++++++++---- 1 file changed, 85 insertions(+), 19 deletions(-) diff --git a/srcpkgs/renderdoc/patches/python-3.11.patch b/srcpkgs/renderdoc/patches/python-3.11.patch index 93807f6fe26..cfa65291821 100644 --- a/srcpkgs/renderdoc/patches/python-3.11.patch +++ b/srcpkgs/renderdoc/patches/python-3.11.patch @@ -1,11 +1,20 @@ ---- a/qrenderdoc/Code/pyrenderdoc/function_conversion.h -+++ b/qrenderdoc/Code/pyrenderdoc/function_conversion.h -@@ -303,11 +303,19 @@ funcType ConvertFunc(const char *funcnam +Index: renderdoc-1.21/qrenderdoc/Code/pyrenderdoc/function_conversion.h +=================================================================== +--- renderdoc-1.21.orig/qrenderdoc/Code/pyrenderdoc/function_conversion.h ++++ renderdoc-1.21/qrenderdoc/Code/pyrenderdoc/function_conversion.h +@@ -301,13 +301,30 @@ funcType ConvertFunc(const char *funcnam + { + _frame *frame = PyEval_GetFrame(); ++#if PY_VERSION_HEX >= 0x030B0000 ++ Py_INCREF(frame); ++#endif while(frame) { +#if PY_VERSION_HEX >= 0x030B0000 -+ global_internal_handle = PyDict_GetItemString(PyFrame_GetGlobals(frame), "_renderdoc_internal"); ++ PyObject *f_globals = PyFrame_GetGlobals(frame); ++ global_internal_handle = PyDict_GetItemString(f_globals, "_renderdoc_internal"); ++ Py_DECREF(f_globals); +#else global_internal_handle = PyDict_GetItemString(frame->f_globals, "_renderdoc_internal"); +#endif @@ -13,73 +22,130 @@ if(global_internal_handle) break; +#if PY_VERSION_HEX >= 0x03090000 -+ frame = PyFrame_GetBack(frame); ++ do { ++ PyFrameObject *f_back = PyFrame_GetBack(frame); ++ Py_DECREF(frame); ++ frame = f_back; ++ } while (0); +#else frame = frame->f_back; +#endif } } ---- a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp -+++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp -@@ -85,6 +85,15 @@ extern "C" PyObject *PyInit_qrenderdoc(v +Index: renderdoc-1.21/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp +=================================================================== +--- renderdoc-1.21.orig/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp ++++ renderdoc-1.21/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp +@@ -85,6 +85,33 @@ extern "C" PyObject *PyInit_qrenderdoc(v extern "C" PyObject *WrapBareQWidget(QWidget *); extern "C" QWidget *UnwrapBareQWidget(PyObject *); +#if PY_VERSION_HEX <=0x030B0000 -+#define PyFrame_GetGlobals(x) (x)->f_globals ++static inline PyObject * ++PyFrame_GetGlobals(PyFrameObject *frame) ++{ ++ PyObject *f_globals = frame->f_globals; ++ Py_INCREF(f_globals); ++ return f_globals; ++} +#endif + +#if PY_VERSION_HEX <=0x03090000 -+#define PyFrame_GetBack(x) (x)->f_back -+#define PyFrame_GetCode(x) (x)->f_code ++static inline PyFrameObject * ++PyFrame_GetBack(PyFrameObject *frame) ++{ ++ PyFrameObject *f_back = frame->f_back; ++ Py_INCREF(f_back); ++ return f_back; ++} ++static inline PyCodeObject * ++PyFrame_GetCode(PyFrameObject *frame) ++{ ++ PyCodeObject *f_code = frame->f_code; ++ Py_INCREF(f_code); ++ return f_code; ++} +#endif + // little utility function to convert a PyObject * that we know is a string to a QString static inline QString ToQStr(PyObject *value) { -@@ -1213,7 +1222,7 @@ PyObject *PythonContext::outstream_write +@@ -1211,21 +1238,28 @@ PyObject *PythonContext::outstream_write + { + _frame *frame = PyEval_GetFrame(); ++ Py_XINCREF(frame); ++ while(frame) { - PyObject *globals = frame->f_globals; ++ PyFrameObject *oframe = frame; + PyObject *globals = PyFrame_GetGlobals(frame); if(globals) { ++ Py_DECREF(globals); OutputRedirector *global = -@@ -1225,7 +1234,7 @@ PyObject *PythonContext::outstream_write + (OutputRedirector *)PyDict_GetItemString(globals, "_renderdoc_internal"); +- if(global) ++ if(global) { + context = global->context; ++ Py_DECREF(globals); ++ } + } + if(context) break; - frame = frame->f_back; + frame = PyFrame_GetBack(frame); ++ Py_DECREF(oframe); } } -@@ -1248,7 +1257,7 @@ PyObject *PythonContext::outstream_write +@@ -1239,6 +1273,7 @@ PyObject *PythonContext::outstream_write + rdcstr message = text; + + _frame *frame = PyEval_GetFrame(); ++ Py_XINCREF(frame); + + while(message.back() == '\n' || message.back() == '\r') + message.pop_back(); +@@ -1248,7 +1283,9 @@ PyObject *PythonContext::outstream_write if(frame) { - filename = ToQStr(frame->f_code->co_filename); -+ filename = ToQStr(PyFrame_GetCode(frame)->co_filename); ++ PyCodeObject *code = PyFrame_GetCode(frame); ++ filename = ToQStr(code->co_filename); ++ Py_DECREF(code); line = PyFrame_GetLineNumber(frame); } -@@ -1278,7 +1287,7 @@ int PythonContext::traceEvent(PyObject * +@@ -1278,12 +1315,14 @@ int PythonContext::traceEvent(PyObject * PythonContext *context = (PythonContext *)thisint; PyObject *compiled = PyDict_GetItemString(obj, "compiled"); - if(compiled == (PyObject *)frame->f_code && what == PyTrace_LINE) -+ if(compiled == (PyObject *)PyFrame_GetCode(frame) && what == PyTrace_LINE) ++ PyCodeObject *code = PyFrame_GetCode(frame); ++ if(compiled == (PyObject *)code && what == PyTrace_LINE) { context->location.line = PyFrame_GetLineNumber(frame); -@@ -1361,7 +1370,7 @@ extern "C" void HandleException(PyObject + emit context->traceLine(context->location.file, context->location.line); + } ++ Py_DECREF(code); + + if(context->shouldAbort()) + { +@@ -1361,7 +1400,9 @@ extern "C" void HandleException(PyObject if(frame) { - filename = ToQStr(frame->f_code->co_filename); -+ filename = ToQStr(PyFrame_GetCode(frame)->co_filename); ++ PyCodeObject *code = PyFrame_GetCode(frame); ++ filename = ToQStr(code->co_filename); ++ Py_DECREF(code); linenum = PyFrame_GetLineNumber(frame); }