Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trace code run in global scope using sys.settrace?

Tags:

python

Say I have a piece of code like this:

import sys

def printer(frame, event, arg):
    print(frame, event, arg)
    return printer

sys.settrace(printer)
x = 1
sys.settrace(None)

Since

The trace function is invoked (with event set to 'call') whenever a new local scope is entered

The above code outputs nothing. See my previous question.

So is there a way to trace lines in global scope, like x = 1?

like image 467
laike9m Avatar asked Oct 30 '25 01:10

laike9m


1 Answers

sys.settrace sets the global trace function. This trace function is the one invoked whenever a new Python stack frame is entered ('call' events), and its return value is the new scope's local trace function. The local trace function of the active stack frame is the one used for all other event types.

You need to set the local trace function of an existing stack frame, but setting the global trace function doesn't help you do that. To set an existing frame's local trace function, you can manually assign the f_trace attribute of the frame object to the function you want. For example, to set the current frame's local trace function:

import sys
sys._getframe().f_trace = whateverfunc

Note that local trace functions will not be invoked if there is no global trace function, so you need to set the global trace function too. (This doesn't seem to be documented.)

You can combine sys.settrace and manual f_trace assignment to trace both new and existing stack frames; for example, on a 'return' event, you can check the local trace function of the frame you're about to return to and set that trace function to whatever you want. The bdb debugger framework source code is a good example of how to work with trace functions.

like image 82
user2357112 supports Monica Avatar answered Nov 01 '25 16:11

user2357112 supports Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!