Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-91462: Make lltrace output human-readable. #91463

Merged
merged 14 commits into from Apr 16, 2022
Merged

Conversation

sweeneyde
Copy link
Member

@sweeneyde sweeneyde commented Apr 12, 2022

  • 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:

#91462

@AlexWaygood AlexWaygood added the type-feature A feature request or enhancement label Apr 12, 2022
@sweeneyde
Copy link
Member Author

sweeneyde commented Apr 12, 2022

Example output:

In example.py:

__ltrace__ = 1

def gen():
    yield 10
    yield 20

def main():
    for x in gen():
        x = x * x
        print(x)

main()

Result:

Resuming frame for 'main' in module '__main__'
stack=[]
0: RESUME 0
stack=[]
2: LOAD_GLOBAL 1
stack=[<nil>, <function gen at 0x0000024AF8E92360>, ]
14: PRECALL 0
stack=[<nil>, <function gen at 0x0000024AF8E92360>, ]
18: CALL 0
Resuming frame for 'gen' in module '__main__'
stack=[]
0: RETURN_GENERATOR
Resuming frame for 'main' in module '__main__'
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
28: GET_ITER
Resuming frame for 'gen' in module '__main__'
stack=[None, ]
2: POP_TOP
stack=[]
4: RESUME 0
stack=[]
6: LOAD_CONST 1
stack=[10, ]
8: YIELD_VALUE
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
34: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 10, ]
36: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 10, 10, ]
38: BINARY_OP 5
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 100, ]
42: STORE_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
44: LOAD_GLOBAL 3
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, ]
56: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, 100, ]
58: PRECALL 1
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, 100, ]
62: CALL 1
100
stack=[<generator object gen at 0x0000024AF8CB8AE0>, None, ]
72: POP_TOP
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
74: JUMP_BACKWARD 23
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
30: FOR_ITER 22
Resuming frame for 'gen' in module '__main__'
stack=[None, ]
10: RESUME 1
stack=[None, ]
12: POP_TOP
stack=[]
14: LOAD_CONST 2
stack=[20, ]
16: YIELD_VALUE
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
34: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 20, ]
36: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 20, 20, ]
38: BINARY_OP 5
stack=[<generator object gen at 0x0000024AF8CB8AE0>, 400, ]
42: STORE_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
44: LOAD_GLOBAL 3
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, ]
56: LOAD_FAST 0
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, 400, ]
58: PRECALL 1
stack=[<generator object gen at 0x0000024AF8CB8AE0>, <nil>, <built-in function print>, 400, ]
62: CALL 1
400
stack=[<generator object gen at 0x0000024AF8CB8AE0>, None, ]
72: POP_TOP
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
74: JUMP_BACKWARD 23
stack=[<generator object gen at 0x0000024AF8CB8AE0>, ]
30: FOR_ITER 22
Resuming frame for 'gen' in module '__main__'
stack=[None, ]
18: RESUME 1
stack=[None, ]
20: POP_TOP
stack=[]
22: LOAD_CONST 0
stack=[None, ]
24: RETURN_VALUE
stack=[]
76: LOAD_CONST 0
stack=[None, ]
78: RETURN_VALUE
Resuming frame for '<module>'
stack=[None, ]
36: POP_TOP
stack=[]
38: LOAD_CONST 3
stack=[None, ]
40: RETURN_VALUE

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this a lot. Thanks, it will be much more useful now!

Lib/test/test_lltrace.py Show resolved Hide resolved
Lib/test/test_lltrace.py Show resolved Hide resolved
class TestLLTrace(unittest.TestCase):

def run_code(self, code):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Surprised there isn't already a utility for this.)

x = 42
y = -x
dont_trace_1()
__ltrace__ = 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tripped me over! :-) It almost seems like a bug that the feature is called LLTRACE but the dunder is __ltrace__...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be a decade-old typo introduced here: 3c1e481

We could maybe accept both __ltrace__ and __lltrace__ at this point?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, just change to __lltrace__. This feature is too niche to require backward compatibility (nobody complained when it was broken 10 years ago :-).

Python/ceval.c Outdated Show resolved Hide resolved
Python/ceval.c Outdated Show resolved Hide resolved
Python/ceval.c Show resolved Hide resolved
Python/ceval.c Outdated Show resolved Hide resolved
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't change a thing! Land it.

@sweeneyde
Copy link
Member Author

I'll do the __ltrace__ --> __lltrace__ in a new PR.

@sweeneyde
Copy link
Member Author

Thanks for the reviews!

@sweeneyde sweeneyde deleted the lltrace branch April 16, 2022 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants