Tuesday, 15 December 2015

Tracing python code

‘sys.settrace(tracefunc)’ function is used to implement source code debugger in python. This function is specific to a thread. To support multiple threads, this function must be registered using threading.settrace(func) method.

How a trace function (tracefunc) defined?
Trace function should have three arguments frame, event, and arg.

Argument
Meaning
frame
Represents current stack frame
event
Event can be 'call', 'line', 'return', 'exception', 'c_call', 'c_return', or 'c_exception'. Next table explain in detail.
arg
Arg depends on event type

Following table explains different type of events and their meaning.
event
meaning
‘call’
A function is called (or) some other code block is entered. Value of arg is None. Return value specifies the local trace function.
‘line’
The interpreter is about to execute a new line of code or re-execute the condition of a loop. Value of arg is set to None.
‘return’
Function is about to return. ‘arg’ is the value that will be returned, or None if the event is caused by an exception being raised
‘exception’
Specifies an exception has occurred. arg is a tuple (exception, value, traceback). Return value specifies the new local trace function.
‘c_call’
A C function is about to be called. ‘arg’ is the c function object.
‘c_return’
A C function has returned. ‘arg’ is the c function object.
c_exception
A c function has raised exception. ‘arg’ is the c function object.
  

test.py
import sys

def factorial(num):
 i=1
 result = 1
 while(i <= num):
  result *= i
  i+=1
 return result
 
def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        print("line", lineno)

    return traceit
 
sys.settrace(traceit)
print("5!=",factorial(5))

$ python3 test.py 
line 4
line 5
line 6
line 7
line 8
line 6
line 7
line 8
line 6
line 7
line 8
line 6
line 7
line 8
line 6
line 7
line 8
line 6
line 9
5!= 120

‘frame.f_lineno’  represents the line number about to be run. Go through the output of test.py, you can easily figure it out, what is happening. Above program prints the line number, whenever interpreter about to execute new line.

By using ‘linecache’ module, we can print the source code at specific line in a file.


test.py
import sys
import linecache

def factorial(num):
 i=1
 result = 1
 while(i <= num):
  result *= i
  i+=1
 return result
 
def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        line = linecache.getline("test.py", lineno)
        print("line", lineno, line)

    return traceit
 
sys.settrace(traceit)
print("5!=",factorial(5))

$ python3 test.py 
line 5  i=1

line 6  result = 1

line 7  while(i <= num):

line 8   result *= i

line 9   i+=1

line 7  while(i <= num):

line 8   result *= i

line 9   i+=1

line 7  while(i <= num):

line 8   result *= i

line 9   i+=1

line 7  while(i <= num):

line 8   result *= i

line 9   i+=1

line 7  while(i <= num):

line 8   result *= i

line 9   i+=1

line 7  while(i <= num):

line 10  return result

5!= 120





Previous                                                 Next                                                 Home

No comments:

Post a Comment