Skip to content

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

@sweeneyde sweeneyde requested a review from gvanrossum April 15, 2022 09:17
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!

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 :-).

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.

4 participants