How to trace program execution mentally step by step
mental execution model, variable state tracking, execution order, tracing loops, side effects
Mental Execution
The fastest way to find a bug without a debugger is to become the computer. Read each line in execution order, maintaining a table of variable values in your head or on paper. When a variable holds a value you did not expect, you found the propagation point.
How to Trace
Create a simple table: columns are variable names, rows are execution steps. Update each cell as you encounter an assignment. Track conditional branches -- write the condition and its evaluated result. When you hit a loop, trace the first two iterations and the last one.
function sumPositive(nums) {
let total = 0; // total = 0
for (let i = 0; i <= nums.length; i++) { // bug: <= instead of <
if (nums[i] > 0) {
total += nums[i]; // i=3: nums[3] is undefined, silent failure
}
}
return total;
}
// Trace: i=0,1,2,3. At i=3 nums[3]=undefined, condition false.
// Bug found: off-by-one in loop bound
Side Effects Are Hidden State
Functions that modify external state -- globals, database rows, files -- make tracing harder because the effect is not visible in the local scope. Mark every function call that has side effects as you trace. If you cannot tell whether a function has side effects, assume it does and check its definition before continuing.
