2

I am writing some code in C++ that has to compute lots of ray/object intersections and I'm getting a very weird bug that I don't understand.

On some very large instances (lots of triangles and rays) my program segfaults. I've been trying to figure out the source of these segfaults but I've been stumped. I've looked through my code and it doesn't seem like I should ever try to index off the end of an array or access a null pointer. It also doesn't seem like my computer is running out of memory. When I monitor it, it looks like there's still a few hundred megabytes free.

While debugging, I attempted the following: I inserted two print statements in my code in an attempt to determine the exact interesection computation that was causing the segfault. Unfortunately for me, when I inserted the print statements and ran the program again, everything worked. It didn't segfault. So if I remove those two print statements and I run the program it segfaults, and if I keep them in it works fine (although much slower as it has to print everything). Everything else is kept exactly the same, except for the removal/addition of those print statements.

What could possibly cause this to happen? How would adding print statements to a c++ program possibly cause it to not segfault?

If it helps at all, the algorithm is only a single thread and I compiled everything using g++ in Linux.

martega
  • 2,103
  • 2
  • 21
  • 33
  • 5
    Some code for us to look at would be nice. – Mysticial May 04 '12 at 23:44
  • Undefined behaviour can cause anything. – mfontanini May 04 '12 at 23:48
  • 2
    According to my crystal ball, the error leading to the undefined behavior is on line 42. – Jerry Coffin May 04 '12 at 23:52
  • 2
    The console is feeling lonely because you aren't printing enough to it. It's telling the OS to muck with your program because of this. Ok, maybe that is not the reason. – James McNellis May 04 '12 at 23:56
  • Undefined behavior can, within certain bounds of course, cause "anything". Of course, your computer isn't going to be able to make purple dragons fly out of your nostrils, but many other things might happen, limited to what the OS will allow a user-mode program to get away with. (For instance, there's very little chance that "undefined behavior" could result in deleting your whole hard drive.) – phonetagger May 05 '12 at 00:02
  • ...having said that, undefined behavior is often very repeatable on a given system, and if you look at the underlying machine code you'll see that though the source code describes an operation of undefined behavior, the resulting machine code does have a very well defined behavior, though not what the author intended, which is why it's often very repeatable. Within the bounds of a given system, constructs with nominally "undefined behavior" are regularly used by embedded system developers, driver writers, and systems programmers, always with specifically intended purposes. – phonetagger May 05 '12 at 00:06
  • If you're not familiar with debuggers, NOW is the time to get familiar with them, not later. Though it will take you a couple or three days to learn how to effectively use them, in cases like these, the debugger will tell you in about 15 seconds exactly where your bug is (once you learn how to interpret its results, show a stack backtrace, etc.). Without a debugger, you're left with a moving target that's really hard to debug. cout/printf debugging works fine for logic errors, but rarely helps for segfaults. – phonetagger May 05 '12 at 00:11
  • @JamesMcNellis: It probably is the real reason though. Once upon a time, consoles were the center of everybody's attention all the time. With all these new-fangled windowing thingies, they feel marginalized. – Jerry Coffin May 05 '12 at 00:11
  • 1
    Perhaps I should have suggested a specific debugger? I use the DDD graphical debugger interface with GDB running underneath. If you're masochistic, you can use GDB directly. I think most Linux gurus do. – phonetagger May 05 '12 at 00:16
  • http://en.wikipedia.org/wiki/Heisenbug – jamesdlin May 05 '12 at 00:17
  • No. Line 42 is a side effect. The root cause is the unitialized pointer on line 17. – EvilTeach Feb 05 '16 at 20:34

2 Answers2

4

What could possibly cause this to happen? How would adding print statements to a c++ program possibly cause it to not segfault?

Welcome to undefined behaviour.

You need to replace your arrays/pointers/etc with self-checking versions and prove, rather than guesstimate, that you don't have any bugs in these areas.

Puppy
  • 144,682
  • 38
  • 256
  • 465
3

The fact that inserting print statements "fixes" the seg fault is a clear indication that you are accessing memory that you shouldn't.

The best thing to do is to take out the print statements, and run your program through a debugger. Since you are working in Linux, compile your program with a -g flag and run it through gdb. It might tell you exactly in which line it segfaults.

Dima
  • 38,860
  • 14
  • 75
  • 115
  • 2
    One of the nasty features of Heisenbugs is that sometimes the debugging environment (like the addition of the diagnostic `printf`s) can mask the bug. If this suggestion fails you might consider wither `valgrind' or `malloc` guards replacement (see the man page, I believe glibc supports them natively). – dmckee --- ex-moderator kitten May 04 '12 at 23:51