While chasing a segfault around a complicated and grouchy c++ program I added several //comments and cout statements, but no 'actual' code. Then, suddenly, for no apparent reason the segfault vanishes.

I'm happy, but still a little worried, because I don't think I fixed anything and there was clearly something wrong.

How can I debug a problem that has disappeared? (sadly I don't have a version that's still giving a segfault, any older versions have other problems)

As an aside, do you think I am mistaken in thinking that I have only added //comments and cout statements? Is it more likely that I accidentally altered something else?

  • 6
    undo your changes and see what happened. And if you don't use version control to manage your changes, this is why you should. – gbjbaanb Jul 7 '15 at 10:48
  • 1
    Also, take the habit of compiling with all warnings & debug info (g++ -Wall -Wextra -g). Use the debugger and other tools (valgrind, or -fsanitize=.... options to GCC) – Basile Starynkevitch Jul 7 '15 at 10:49
  • Read about heisenbugs – Basile Starynkevitch Jul 7 '15 at 10:51
  • 1
    @Jekowl: your bug will come back since you have not identified and fixed it, and it will bite you hard. Better at least make a test case which was triggering the segfault – Basile Starynkevitch Jul 7 '15 at 11:04
  • 4
    "sadly I don't have a version that's still giving a segfault, any older versions have other problems". That should never happen. Use source control. Do it. No really. There's no excuse for not using it. No, you're not the exception. – MetaFight Jul 7 '15 at 12:20

Getting a segmentation fault only happens when you have invoked undefined behaviour. And undefined behaviour means that the normal rules of a programming language don't apply: whatever the run-time system does is by definition OK, and you don't get to complain about it. It might even do the expected thing, just to confuse you.

In particular, adding debug statements can change a program so that it raises exceptions where it didn't before, or vice versa. Indeed, this is expected, because detecting memory access violations depends on how precisely things are laid out in memory, and any code you add changes these details.

Therefore, your program was definitely wrong before, and if you don't get exceptions now, it is almost certainly still wrong, only less obviously wrong. It is much more likely that introducing debug messages changed the variety of undefined behaviour you get than that you fixed your logic and didn't notice.

  • You can get segfaults from well defined but erroneous behavior. A case from 20 years ago that sticks in my mind involved trying to store a real mode pointer into a protected mode pointer. – Loren Pechtel Jul 7 '15 at 22:54

Segfaults often are affected by whatever garbage happened to be in the memory you're erroneously trying to access. Adding a cout near the bug can change that. I've also had bugs that are dependent on what memory location a pointer happened to be assigned to. Move the pointer by adding "irrelevant" code, and it changes the behavior.

That's why the safest way to debug such problems is using a debugger, because it doesn't change the conditions. It also happens to be the fastest way, usually instantly giving you the exact line the bug occurs and the exact state of the variables at that point, although the root cause is often an assignment that occurred previously. And you don't have the overhead of waiting for compiles. There's really no excuse not to learn how to use a debugger.

Not the answer you're looking for? Browse other questions tagged or ask your own question.