Visualising the Call Stack
Use Python's sys module and print tracing to observe stack frames growing and shrinking, and understand stack-overflow risks in deep recursion.
What Is the Call Stack?
Every function call in Python creates a stack frame on the call stack. The frame stores the function's local variables, its return address (where execution resumes after the function returns), and the current instruction pointer. When a function returns, its frame is popped and control passes back to the caller. The call stack grows downward with each call and shrinks with each return.
Understanding the call stack is essential for debugging recursive code, estimating memory usage, and avoiding stack overflow errors in deep recursion.
import traceback
def outer():
inner()
def inner():
# Print the current call stack
traceback.print_stack()
outer()
# Shows: module -> outer -> innerObserving Stack Frames with sys
Python's sys module provides tools to inspect the call stack at runtime. sys._getframe(n) returns the stack frame n levels above the current function. Each frame has a f_locals dict of local variables and f_code.co_name for the function name. Inserting debug prints inside a recursive function reveals how frames accumulate and dissolve.
import sys
def countdown(n):
depth = 0
frame = sys._getframe(0)
while frame:
depth += 1
frame = frame.f_back
print(' ' * (n * 2) + f'countdown({n}) called, stack depth={depth}')
if n <= 0:
return
countdown(n - 1)
print(' ' * (n * 2) + f'countdown({n}) returning')
countdown(3)