Is this program written in C or C++, by any chance? In that case, you can’t conclude anything from probabilistic data—because you’re probably hunting memory corruption, commenting out lines affects memory layout, and memory layout affects the symptoms of memory corruption. Actually, this problem is pretty general; anything that looks like a probabilistic software crash needs a source of entropy to randomize it, and usually this “entropy” will be in the form of a fragile dependency on timing or memory arrangement which interacts with attempts to measure it in impossibly confusing ways. (This is why using C and C++ is usually a terrible idea, and why threads are so feared.)
(This is why using C and C++ is usually a terrible idea, and why threads are so feared.)
I was with you up to this parenthetical. The same problems affect every other programming language, though perhaps with different root causes. Race conditions are hardly language-dependent.
The probability of getting a race condition, given that you’re programming in Haskell, is orders of magnitude lower than the probability of getting a race condition, given that you’re programming in C or C++.
That may well be true. I do have some other constraints, though. For example, does Haskell have a well-supported GUI library that works on Windows and talks to OpenGL?
Haskell requires bending your brain in ways that are often uncomfortable to non-mathematicians. I, personally, use Python, which strikes a balance between race avoidance and library support. I meant more to argue that race conditions are language-dependent than to recommend Haskell as a perfect programming language for any purpose.
Not different root causes, fewer root causes. Threading problems and race conditions exist in all languages, but memory corruption does not; the majority of languages won’t let you do things like write out of bounds or use after free.
Yes, memory corruption in particular is no longer an issue in most higher languages, but memory management in general has become more complicated and less transparent. The Law of Leaky Abstractions ruins everything.
In any case this is reasonably off-topic for this post, so I won’t belabor the point further.
Yes, it’s C++. I’m reasonably convinced the problem was a race condition in initialising the GUI; it appears that the debug logger would try to write to a text field that might or might not exist, probably because a different thread was creating it. (I don’t have full control of the threading since I’m using Qt for my GUI stuff, so exactly when my code is called is unfortunately a bit black-box-ish.) I believe I resolved the issue by introducing a special debug stream for use during startup, which doesn’t try to write to the GUI but instead writes to a log file.
Please note that there are tools to track such memory corruption issues, like Valgrind. Using C and C++ isn’t such a bad idea in itself (for some tasks, it is arguably the most appropriate language) but using them without using the related tools to track memory corruption is.
In a Unix environment that would have been my first thought. However this is Windows. (Yes, yes, C++ on Windows, my geek penis just shrank two inches, whatever.) As far as I could tell from a quick Google, valgrind isn’t supported on Windows. (I’ll be delighted if anyone tells me this is wrong.)
gdb is supported on Windows, and I did use that; but the program obstinately refused to crash in the debugger, presumably because the timing changed. Race conditions for the win…
Is this program written in C or C++, by any chance? In that case, you can’t conclude anything from probabilistic data—because you’re probably hunting memory corruption, commenting out lines affects memory layout, and memory layout affects the symptoms of memory corruption. Actually, this problem is pretty general; anything that looks like a probabilistic software crash needs a source of entropy to randomize it, and usually this “entropy” will be in the form of a fragile dependency on timing or memory arrangement which interacts with attempts to measure it in impossibly confusing ways. (This is why using C and C++ is usually a terrible idea, and why threads are so feared.)
I was with you up to this parenthetical. The same problems affect every other programming language, though perhaps with different root causes. Race conditions are hardly language-dependent.
The probability of getting a race condition, given that you’re programming in Haskell, is orders of magnitude lower than the probability of getting a race condition, given that you’re programming in C or C++.
That may well be true. I do have some other constraints, though. For example, does Haskell have a well-supported GUI library that works on Windows and talks to OpenGL?
Haskell requires bending your brain in ways that are often uncomfortable to non-mathematicians. I, personally, use Python, which strikes a balance between race avoidance and library support. I meant more to argue that race conditions are language-dependent than to recommend Haskell as a perfect programming language for any purpose.
Not different root causes, fewer root causes. Threading problems and race conditions exist in all languages, but memory corruption does not; the majority of languages won’t let you do things like write out of bounds or use after free.
Yes, memory corruption in particular is no longer an issue in most higher languages, but memory management in general has become more complicated and less transparent. The Law of Leaky Abstractions ruins everything.
In any case this is reasonably off-topic for this post, so I won’t belabor the point further.
Yes, it’s C++. I’m reasonably convinced the problem was a race condition in initialising the GUI; it appears that the debug logger would try to write to a text field that might or might not exist, probably because a different thread was creating it. (I don’t have full control of the threading since I’m using Qt for my GUI stuff, so exactly when my code is called is unfortunately a bit black-box-ish.) I believe I resolved the issue by introducing a special debug stream for use during startup, which doesn’t try to write to the GUI but instead writes to a log file.
Please note that there are tools to track such memory corruption issues, like Valgrind. Using C and C++ isn’t such a bad idea in itself (for some tasks, it is arguably the most appropriate language) but using them without using the related tools to track memory corruption is.
In a Unix environment that would have been my first thought. However this is Windows. (Yes, yes, C++ on Windows, my geek penis just shrank two inches, whatever.) As far as I could tell from a quick Google, valgrind isn’t supported on Windows. (I’ll be delighted if anyone tells me this is wrong.)
gdb is supported on Windows, and I did use that; but the program obstinately refused to crash in the debugger, presumably because the timing changed. Race conditions for the win…