printf debugging
- C course
- Intermediate
- Lesson 98/116
- 5 min
Learn printf debugging tactics.
Tracing with printf
Sometimes gdb is impractical; for instance the program is very slow or runs on a server. In those cases printf debugging is the fastest path. You sprinkle temporary printf or fprintf(stderr, ...) calls into the code.
Example: fprintf(stderr, "trace: start n=%d\n", n);. Using stderr keeps tracing separate from normal output; you can redirect it with ./prog 2> log.txt. A good trace message includes the function name and the values of key variables. Once the bug is found, these calls are removed; they do not stay in production code.
Function entry and exit
To check whether a function is called and with what values, you place trace lines at entry and exit. This shows the function's flow from start to finish.
Example: int process(int n) { fprintf(stderr, "trace: start n=%d\n", n); int result = n * 2; fprintf(stderr, "trace: end result=%d\n", result); return result; }. The entry message shows parameters, the exit message shows the return value. When main calls this function and prints the result, you see both the trace and the result together. This pattern helps find which layer holds the bug, especially in deep call chains.
Practice Write a traced function
Write int process(int n). At entry print fprintf(stderr, "iz: başla n=%d\n", n);, compute int result = n * 2;, at exit print fprintf(stderr, "iz: bit result=%d\n", result); and return result;. In main call it with printf("%d\n", process(5));.
Starter code
#include <stdio.h>
// Write the process function with entry and exit traces
// Call process(5) in main and print
int main(void) {
return 0;
}Sample solution
#include <stdio.h>
int process(int n) {
fprintf(stderr, "iz: başla n=%d\n", n);
int result = n * 2;
fprintf(stderr, "iz: bit result=%d\n", result);
return result;
}
int main(void) {
printf("%d\n", process(5));
return 0;
}Expected output
iz: başla n=5 iz: bit result=10 10
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match the tracing patterns
| Term | Meaning |
|---|---|
fprintf(stderr,...) |
Trace to error stream |
printf(...) |
Trace to stdout |
2> log.txt |
Redirect trace to file |
iz: başla |
Function entry |
2 Complete the trace output
fprintf(stderr, "iz: başla n=%d
", ____);
fprintf(stderr, "iz: başla n=%d
", n);
Explanation: fprintf(stderr, ..., n) writes the value of n to the trace stream.
3 Why does printf debugging use stderr?
- Because stdout is unavailable
- Because stderr is faster
- Because stderr is separate from stdout Correct answer
- Because stderr speeds up the compiler
Explanation: stderr is separate from stdout, so tracing stays apart from normal output.