I am always thinking, what can I print so that I know my program works? I try to make this easy and still useful. Sometimes a little effort to make it easy pays off big.
In Fortran 4, what a pain.
PRINT (5, 20) I, J 20 FORMAT (2HI=, I10, 4H, J=, I10)
In C, a little better.
printf(stderr, "i=%d, j=%d\n", i, j);
In tight situations I've built my own mechanisms for collecting debugging print output.
PL/1 Compiler used a macro to print any register legibly and non-destructively.
TRACE "Symbol Table Size", B6
State Ports let me write a byte to a custom made peripheral for debugging early multi-microprocessors.
OUT 12, I
Spinometer similarly modulated a single microcontroller pin to move a meter showing variables.
meter (10, threshold, 1024);
Test Point logged objects in a circular buffer without any storage allocation or print formatting until read.
Exploratory Parsing captured failed cases as legitimate input and tallied it with all other results.
fact = key value | other_char
Rubific parsed a subset of Ruby expressions tracing recursive entry and exit as it went.
trace("( ... ") trace(" ... )")