Why Adding a printf Can “Bless” a Crashing C Program
A humorous tale reveals how an uninitialized stack variable caused a segmentation fault in C, how inserting a printf unintentionally altered memory to hide the bug, and why proper debugging with GDB is essential to understand such hidden issues.
The story begins with programmer Zhang fixing a bug late at night, compiling a C program that crashes with a segmentation fault:
root@ubuntu:printf# gcc -g test.c -o test
root@ubuntu:printf# ./test
Segmentation faultAfter a tongue‑in‑cheek “Buddha blessing” (adding a mysterious code snippet), the program runs without crashing, leading colleagues to marvel at the miracle.
Technical Investigation
Colleague Nicholas Li examines the failure by removing the “blessed” code and debugging with GDB. He discovers that the function bar() uses a local variable idx that was never initialized, so it contains whatever residual data was left on the stack.
During a prior call to fool(), the statement memset(array, 1, sizeof(array)) filled a buffer with the byte value 0x01. This left the stack memory at the location of idx filled with 0x01010101 (decimal 16843009). When bar() later accesses buf[idx] = 'A', it reads an out‑of‑bounds address, causing the segmentation fault.
Li demonstrates that the address of array[9] in fool() is identical to the address of idx in bar(), confirming the stack‑reuse explanation.
Why the printf “fixed” the crash
When the team added a printf call (the so‑called “blessing”), the extra function call altered the stack layout. The printf execution overwrote the residual 0x01010101 value, effectively setting idx to zero. Consequently, buf[0] = 'A' accessed a valid location, and the program no longer segfaulted.
This phenomenon illustrates a classic debugging pitfall: inserting logging statements can change timing or memory layout, masking the original defect without actually fixing it.
Further Experiments
Li attempts to replicate the “blessing” by replacing the original printf with a simple printf("Hello, World!\n"). The program crashes again, because the new call does not overwrite the critical stack location. After a second modification—adding a newline character—the stack is again altered just enough to zero out idx, and the program runs successfully.
The final takeaway, presented in a sober afterword, emphasizes that 99% of the time a printf does not solve the bug; it merely hides it. Proper analysis of how logging affects program state, especially in low‑level C code, is essential.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
