Commit 8ed317f1 authored by costypetrisor's avatar costypetrisor Committed by Victor Stinner

bpo-34113: Fix a crash when using LLTRACE is on (GH-8517)

Fix a crash on negative STACKADJ() when Low-Level trace (LLTRACE) is enabled.
parent 944451cd
import os
import textwrap
import unittest
from test import support
from test.support.script_helper import assert_python_ok
class TestLLTrace(unittest.TestCase):
def test_lltrace_does_not_crash_on_subscript_operator(self):
# If this test fails, it will reproduce a crash reported as
# bpo-34113. The crash happened at the command line console of
# debug Python builds with __ltrace__ enabled (only possible in console),
# when the interal Python stack was negatively adjusted
with open(support.TESTFN, 'w') as fd:
self.addCleanup(os.unlink, support.TESTFN)
fd.write(textwrap.dedent("""\
import code
console = code.InteractiveConsole()
console.push('__ltrace__ = 1')
console.push('a = [1, 2, 3]')
console.push('a[0] = 1')
print('unreachable if bug exists')
"""))
assert_python_ok(support.TESTFN)
if __name__ == "__main__":
unittest.main()
Fixed crash on debug builds when opcode stack was adjusted with negative
numbers. Patch by Constantin Petrisor.
...@@ -762,16 +762,26 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) ...@@ -762,16 +762,26 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
assert(STACK_LEVEL() <= co->co_stacksize); } assert(STACK_LEVEL() <= co->co_stacksize); }
#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \ #define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \
BASIC_POP()) BASIC_POP())
#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \ #define STACK_GROW(n) do { \
assert(n >= 0); \
(void)(BASIC_STACKADJ(n), \
lltrace && prtrace(TOP(), "stackadj")); \ lltrace && prtrace(TOP(), "stackadj")); \
assert(STACK_LEVEL() <= co->co_stacksize); } assert(STACK_LEVEL() <= co->co_stacksize); \
} while (0)
#define STACK_SHRINK(n) do { \
assert(n >= 0); \
(void)(lltrace && prtrace(TOP(), "stackadj")); \
(void)(BASIC_STACKADJ(-n)); \
assert(STACK_LEVEL() <= co->co_stacksize); \
} while (0)
#define EXT_POP(STACK_POINTER) ((void)(lltrace && \ #define EXT_POP(STACK_POINTER) ((void)(lltrace && \
prtrace((STACK_POINTER)[-1], "ext_pop")), \ prtrace((STACK_POINTER)[-1], "ext_pop")), \
*--(STACK_POINTER)) *--(STACK_POINTER))
#else #else
#define PUSH(v) BASIC_PUSH(v) #define PUSH(v) BASIC_PUSH(v)
#define POP() BASIC_POP() #define POP() BASIC_POP()
#define STACKADJ(n) BASIC_STACKADJ(n) #define STACK_GROW(n) BASIC_STACKADJ(n)
#define STACK_SHRINK(n) BASIC_STACKADJ(-n)
#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER)) #define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
#endif #endif
...@@ -1133,7 +1143,7 @@ main_loop: ...@@ -1133,7 +1143,7 @@ main_loop:
PyObject *second = SECOND(); PyObject *second = SECOND();
Py_INCREF(top); Py_INCREF(top);
Py_INCREF(second); Py_INCREF(second);
STACKADJ(2); STACK_GROW(2);
SET_TOP(top); SET_TOP(top);
SET_SECOND(second); SET_SECOND(second);
FAST_DISPATCH(); FAST_DISPATCH();
...@@ -1173,7 +1183,7 @@ main_loop: ...@@ -1173,7 +1183,7 @@ main_loop:
SET_TOP(Py_False); SET_TOP(Py_False);
DISPATCH(); DISPATCH();
} }
STACKADJ(-1); STACK_SHRINK(1);
goto error; goto error;
} }
...@@ -1569,7 +1579,7 @@ main_loop: ...@@ -1569,7 +1579,7 @@ main_loop:
PyObject *container = SECOND(); PyObject *container = SECOND();
PyObject *v = THIRD(); PyObject *v = THIRD();
int err; int err;
STACKADJ(-3); STACK_SHRINK(3);
/* container[sub] = v */ /* container[sub] = v */
err = PyObject_SetItem(container, sub, v); err = PyObject_SetItem(container, sub, v);
Py_DECREF(v); Py_DECREF(v);
...@@ -1584,7 +1594,7 @@ main_loop: ...@@ -1584,7 +1594,7 @@ main_loop:
PyObject *sub = TOP(); PyObject *sub = TOP();
PyObject *container = SECOND(); PyObject *container = SECOND();
int err; int err;
STACKADJ(-2); STACK_SHRINK(2);
/* del container[sub] */ /* del container[sub] */
err = PyObject_DelItem(container, sub); err = PyObject_DelItem(container, sub);
Py_DECREF(container); Py_DECREF(container);
...@@ -2067,7 +2077,7 @@ main_loop: ...@@ -2067,7 +2077,7 @@ main_loop:
} }
} else if (unpack_iterable(seq, oparg, -1, } else if (unpack_iterable(seq, oparg, -1,
stack_pointer + oparg)) { stack_pointer + oparg)) {
STACKADJ(oparg); STACK_GROW(oparg);
} else { } else {
/* unpack_iterable() raised an exception */ /* unpack_iterable() raised an exception */
Py_DECREF(seq); Py_DECREF(seq);
...@@ -2097,7 +2107,7 @@ main_loop: ...@@ -2097,7 +2107,7 @@ main_loop:
PyObject *owner = TOP(); PyObject *owner = TOP();
PyObject *v = SECOND(); PyObject *v = SECOND();
int err; int err;
STACKADJ(-2); STACK_SHRINK(2);
err = PyObject_SetAttr(owner, name, v); err = PyObject_SetAttr(owner, name, v);
Py_DECREF(v); Py_DECREF(v);
Py_DECREF(owner); Py_DECREF(owner);
...@@ -2420,7 +2430,7 @@ main_loop: ...@@ -2420,7 +2430,7 @@ main_loop:
err = PySet_Add(set, item); err = PySet_Add(set, item);
Py_DECREF(item); Py_DECREF(item);
} }
STACKADJ(-oparg); STACK_SHRINK(oparg);
if (err != 0) { if (err != 0) {
Py_DECREF(set); Py_DECREF(set);
goto error; goto error;
...@@ -2641,7 +2651,7 @@ main_loop: ...@@ -2641,7 +2651,7 @@ main_loop:
PyObject *value = SECOND(); PyObject *value = SECOND();
PyObject *map; PyObject *map;
int err; int err;
STACKADJ(-2); STACK_SHRINK(2);
map = PEEK(oparg); /* dict */ map = PEEK(oparg); /* dict */
assert(PyDict_CheckExact(map)); assert(PyDict_CheckExact(map));
err = PyDict_SetItem(map, key, value); /* map[key] = value */ err = PyDict_SetItem(map, key, value); /* map[key] = value */
...@@ -2784,7 +2794,7 @@ main_loop: ...@@ -2784,7 +2794,7 @@ main_loop:
PyObject *cond = TOP(); PyObject *cond = TOP();
int err; int err;
if (cond == Py_True) { if (cond == Py_True) {
STACKADJ(-1); STACK_SHRINK(1);
Py_DECREF(cond); Py_DECREF(cond);
FAST_DISPATCH(); FAST_DISPATCH();
} }
...@@ -2794,7 +2804,7 @@ main_loop: ...@@ -2794,7 +2804,7 @@ main_loop:
} }
err = PyObject_IsTrue(cond); err = PyObject_IsTrue(cond);
if (err > 0) { if (err > 0) {
STACKADJ(-1); STACK_SHRINK(1);
Py_DECREF(cond); Py_DECREF(cond);
} }
else if (err == 0) else if (err == 0)
...@@ -2808,7 +2818,7 @@ main_loop: ...@@ -2808,7 +2818,7 @@ main_loop:
PyObject *cond = TOP(); PyObject *cond = TOP();
int err; int err;
if (cond == Py_False) { if (cond == Py_False) {
STACKADJ(-1); STACK_SHRINK(1);
Py_DECREF(cond); Py_DECREF(cond);
FAST_DISPATCH(); FAST_DISPATCH();
} }
...@@ -2821,7 +2831,7 @@ main_loop: ...@@ -2821,7 +2831,7 @@ main_loop:
JUMPTO(oparg); JUMPTO(oparg);
} }
else if (err == 0) { else if (err == 0) {
STACKADJ(-1); STACK_SHRINK(1);
Py_DECREF(cond); Py_DECREF(cond);
} }
else else
...@@ -2907,7 +2917,7 @@ main_loop: ...@@ -2907,7 +2917,7 @@ main_loop:
PyErr_Clear(); PyErr_Clear();
} }
/* iterator ended normally */ /* iterator ended normally */
STACKADJ(-1); STACK_SHRINK(1);
Py_DECREF(iter); Py_DECREF(iter);
JUMPBY(oparg); JUMPBY(oparg);
PREDICT(POP_BLOCK); PREDICT(POP_BLOCK);
...@@ -3015,7 +3025,7 @@ main_loop: ...@@ -3015,7 +3025,7 @@ main_loop:
val = tb = Py_None; val = tb = Py_None;
exc = TOP(); exc = TOP();
if (exc == NULL) { if (exc == NULL) {
STACKADJ(-1); STACK_SHRINK(1);
exit_func = TOP(); exit_func = TOP();
SET_TOP(exc); SET_TOP(exc);
exc = Py_None; exc = Py_None;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment