Tracing Executions
Overview
This article covers the “Tracing Executions” chapter from The Debugging Book. In this article we will summarize the chapter and discuss how its content could be utilized within the context of the implementation and testing of the Chasten and Cellveyor tools.
Summary
This chapter in The Debugging Book talked about Tracer
and it’s capabilities to monitor and show how a function behaviors and what are its inputs and outputs. Tracer
allows you to observe many features of a program as it runs such as gives you access to see the current line number, variables, and more without having to write out numerous print statements using the command sys.settrace
. This command gives us the ability to trace everything and makes it very simple to the user.
The frame
argument holds the function and its local variables, working in this fashion:
frame.f_lineno
: the current lineframe.f_locals
: the current variables, as a Python dictionaryframe.f_code
: the current code, as aCode
object, with attributes such asframe.f_code.co_name
, or the name of the current function
def traceit(frame: FrameType, event: str, arg: Any) -> Optional[Callable]:
print(event, frame.f_lineno, frame.f_code.co_name, frame.f_locals)
return traceit
The aforementioned function traces the input program and prints out the event, which tells us what happens in the program line by line. The trace
function returns the most important values of the function.
import sys
def remove_html_markup_traced(s):
sys.settrace(traceit)= remove_html_markup(s)
ret None)
sys.settrace(return ret
The tracing function as well can be applied in a class and can work the same as before but on a much more expansive scale. This may improve the efficiency of a program and can easily work and perform the trace
function. The typical usage of Tracer
though in a class is done using the with
command. This would trace everything indented within the with
and everything that is not indented inside of the with
is not subject to tracing.
Tracing can also log while making sure the specific conditional expression does not get changed. The conditional tracer gets a conditional expression to be checked during executions. But only if this condition holds will it list the current status. You can use this for many different expressions and will only get the lines executed that are true to a statement.
with ConditionalTracer(condition='quote'):
remove_html_markup(...)
Reflection
After reading this chapter, we have a better understanding of what tracing entails. We have learned that there are several different ways to trace, from simply using the settrace()
function to writing a complex Tracer
class with conditional logic. We learned about frames and all the different variables within them. We learned how tracing can help improve the efficiency of the debugging process. With this knowledge, we can better understand the process of tracing and be able to implement tracing into our own programs.
Action Items
After reading the article, our focus is on refining debugging by emphasizing the cause-and-effect chain, enhancing test case development, and integrating the scientific method. This approach proves beneficial in diagnosing and resolving bugs, fostering a methodical and systematic debugging process. Documentation practices will be updated, and a commitment to continuous learning will be realized through training programs. These actions aim to empower our team with a robust methodology, drawn from the insights of this chapter, enhancing our ability to debug code effectively because we will have more insights into a program’s behavior.