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

f_trace_opcodes setting and accessing opcodes #80601

Closed
tonybaloney mannequin opened this issue Mar 25, 2019 · 2 comments
Closed

f_trace_opcodes setting and accessing opcodes #80601

tonybaloney mannequin opened this issue Mar 25, 2019 · 2 comments
Labels
3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@tonybaloney
Copy link
Mannequin

tonybaloney mannequin commented Mar 25, 2019

BPO 36420
Nosy @ncoghlan, @tonybaloney

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2019-03-25.02:09:33.064>
created_at = <Date 2019-03-25.00:00:56.272>
labels = ['interpreter-core', 'invalid', '3.8']
title = 'f_trace_opcodes setting and accessing opcodes'
updated_at = <Date 2019-03-25.02:09:33.064>
user = 'https://github.com/tonybaloney'

bugs.python.org fields:

activity = <Date 2019-03-25.02:09:33.064>
actor = 'anthony shaw'
assignee = 'none'
closed = True
closed_date = <Date 2019-03-25.02:09:33.064>
closer = 'anthony shaw'
components = ['Interpreter Core']
creation = <Date 2019-03-25.00:00:56.272>
creator = 'anthony shaw'
dependencies = []
files = []
hgrepos = []
issue_num = 36420
keywords = []
message_count = 2.0
messages = ['338772', '338777']
nosy_count = 2.0
nosy_names = ['ncoghlan', 'anthony shaw']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue36420'
versions = ['Python 3.8']

@tonybaloney
Copy link
Mannequin Author

tonybaloney mannequin commented Mar 25, 2019

The f_trace_opcodes flag for sys.settrace in 3.7 are proving tricky.

I must be missing something but it's not clear how it helps in tracing the opcode about to be executed because it runs before opcode and oparg variables are set by NEXTOPARG(), so the only way to establish the opcode is to look at the frame code and work out the next instruction in the stack.

The documentation references dis, but if you call that for a traceback or using the frame code, you only have the last instruction, not the next one?

def trace(frame, event, args):
  frame.f_trace_opcodes = True
  if event == 'opcode':
    disassemble(frame.f_code, frame.f_lasti)
  return frame

It looks like the emitting of the opcode event needs to come after NEXTOPARG(), but that means if the tracing function were to add any instructions to the stack, that would no longer work.
Alternatively, the opcode could be calculated and added as an argument.

@tonybaloney tonybaloney mannequin added 3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Mar 25, 2019
@tonybaloney
Copy link
Mannequin Author

tonybaloney mannequin commented Mar 25, 2019

Took a while, but I worked out a solution:

import sys
import dis
import traceback
import io

def t(frame, event, args):
   frame.f_trace_opcodes=True
   stack = traceback.extract_stack(frame)
   pad = "   "*len(stack) + "|"
   if event == 'opcode':
      with io.StringIO() as out:
         dis.disco(frame.f_code, frame.f_lasti, file=out)
         lines = out.getvalue().split('\n')
         [print(f"{pad}{l}") for l in lines]
   elif event == 'call':
      print(f"{pad}Calling {frame.f_code}")
   elif event == 'return':
      print(f"{pad}Returning {args}")
   elif event == 'line':
      print(f"{pad}Changing line to {frame.f_lineno}")
   else:
      print(f"{pad}{frame} ({event} - {args})")
   print(f"{pad}----------------------------------")
   return t
sys.settrace(t)
eval('"-".join([letter for letter in "hello"])')

@tonybaloney tonybaloney mannequin closed this as completed Mar 25, 2019
@tonybaloney tonybaloney mannequin added the invalid label Mar 25, 2019
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

No branches or pull requests

0 participants