summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorDennis Sweeney <36520290+sweeneyde@users.noreply.github.com>2022-04-16 21:36:29 (GMT)
committerGitHub <noreply@github.com>2022-04-16 21:36:29 (GMT)
commit8560f4a0f288fec33ba49f85bb872353d631a4dc (patch)
treebde96f3f8e2e1efefd8810d7ec48714567696fc3 /Lib
parent25af5ea40f286df0a578c738c67ab54faceda90a (diff)
downloadcpython-8560f4a0f288fec33ba49f85bb872353d631a4dc.zip
cpython-8560f4a0f288fec33ba49f85bb872353d631a4dc.tar.gz
cpython-8560f4a0f288fec33ba49f85bb872353d631a4dc.tar.bz2
gh-91462: Make lltrace output human-readable. (GH-91463)
* Transform opcodes into opnames * Print the whole stack at each opcode, and eliminate prtrace output at each (push/pop/stackadj) * Display info about the function at each resume_frame
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_lltrace.py97
1 files changed, 89 insertions, 8 deletions
diff --git a/Lib/test/test_lltrace.py b/Lib/test/test_lltrace.py
index 06e33f4..75b377b 100644
--- a/Lib/test/test_lltrace.py
+++ b/Lib/test/test_lltrace.py
@@ -1,21 +1,103 @@
-import os
+import dis
+import sys
import textwrap
import unittest
-from test.support import os_helper
+from test.support import os_helper, verbose
from test.support.script_helper import assert_python_ok
+def example():
+ x = []
+ for i in range(1):
+ x.append(i)
+ x = "this is"
+ y = "an example"
+ print(x, y)
+Py_DEBUG = hasattr(sys, 'gettotalrefcount')
+
+@unittest.skipUnless(Py_DEBUG, "lltrace requires Py_DEBUG")
class TestLLTrace(unittest.TestCase):
+ def run_code(self, code):
+ code = textwrap.dedent(code).strip()
+ with open(os_helper.TESTFN, 'w', encoding='utf-8') as fd:
+ self.addCleanup(os_helper.unlink, os_helper.TESTFN)
+ fd.write(code)
+ status, stdout, stderr = assert_python_ok(os_helper.TESTFN)
+ self.assertEqual(stderr, b"")
+ self.assertEqual(status, 0)
+ result = stdout.decode('utf-8')
+ if verbose:
+ print("\n\n--- code ---")
+ print(code)
+ print("\n--- stdout ---")
+ print(result)
+ print()
+ return result
+
+ def test_lltrace(self):
+ stdout = self.run_code("""
+ def dont_trace_1():
+ a = "a"
+ a = 10 * a
+ def trace_me():
+ for i in range(3):
+ +i
+ def dont_trace_2():
+ x = 42
+ y = -x
+ dont_trace_1()
+ __ltrace__ = 1
+ trace_me()
+ del __ltrace__
+ dont_trace_2()
+ """)
+ self.assertIn("GET_ITER", stdout)
+ self.assertIn("FOR_ITER", stdout)
+ self.assertIn("UNARY_POSITIVE", stdout)
+ self.assertIn("POP_TOP", stdout)
+ self.assertNotIn("BINARY_OP", stdout)
+ self.assertNotIn("UNARY_NEGATIVE", stdout)
+
+ self.assertIn("'trace_me' in module '__main__'", stdout)
+ self.assertNotIn("dont_trace_1", stdout)
+ self.assertNotIn("'dont_trace_2' in module", stdout)
+
+ def test_lltrace_different_module(self):
+ stdout = self.run_code("""
+ from test import test_lltrace
+ test_lltrace.__ltrace__ = 1
+ test_lltrace.example()
+ """)
+ self.assertIn("'example' in module 'test.test_lltrace'", stdout)
+ self.assertIn('LOAD_CONST', stdout)
+ self.assertIn('FOR_ITER', stdout)
+ self.assertIn('this is an example', stdout)
+
+ # check that offsets match the output of dis.dis()
+ instr_map = {i.offset: i for i in dis.get_instructions(example)}
+ for line in stdout.splitlines():
+ offset, colon, opname_oparg = line.partition(":")
+ if not colon:
+ continue
+ offset = int(offset)
+ opname_oparg = opname_oparg.split()
+ if len(opname_oparg) == 2:
+ opname, oparg = opname_oparg
+ oparg = int(oparg)
+ else:
+ (opname,) = opname_oparg
+ oparg = None
+ self.assertEqual(instr_map[offset].opname, opname)
+ self.assertEqual(instr_map[offset].arg, oparg)
+
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 internal Python stack was negatively adjusted
- with open(os_helper.TESTFN, 'w', encoding='utf-8') as fd:
- self.addCleanup(os_helper.unlink, os_helper.TESTFN)
- fd.write(textwrap.dedent("""\
+ stdout = self.run_code("""
import code
console = code.InteractiveConsole()
@@ -23,9 +105,8 @@ class TestLLTrace(unittest.TestCase):
console.push('a = [1, 2, 3]')
console.push('a[0] = 1')
print('unreachable if bug exists')
- """))
-
- assert_python_ok(os_helper.TESTFN)
+ """)
+ self.assertIn("unreachable if bug exists", stdout)
if __name__ == "__main__":
unittest.main()