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 aCodeobject, 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 traceitThe 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)
ret = remove_html_markup(s)
sys.settrace(None)
return retThe 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.