summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 97a734c..a93ceea 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -554,8 +554,16 @@ eval_frame(PyFrameObject *f)
/* Local variable macros */
#define GETLOCAL(i) (fastlocals[i])
-#define SETLOCAL(i, value) do { Py_XDECREF(GETLOCAL(i)); \
- GETLOCAL(i) = value; } while (0)
+
+/* The SETLOCAL() macro must not DECREF the local variable in-place and
+ then store the new value; it must copy the old value to a temporary
+ value, then store the new value, and then DECREF the temporary value.
+ This is because it is possible that during the DECREF the frame is
+ accessed by other code (e.g. a __del__ method or gc.collect()) and the
+ variable would be pointing to already-freed memory. */
+#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
+ GETLOCAL(i) = value; \
+ Py_XDECREF(tmp); } while (0)
/* Start of code */