Optimisation causing crashes?

Started by
15 comments, last by FrancisXavier 15 years, 8 months ago
I've never experienced this before: If I compile with O2, my program crashes. If I use O1 then everything is ok! I can't compile with both debug info and O2, so I'm not sure exactly how to deal with this... If I run with the debugger attached, I get this dialog: Microsoft Visual Studio C Runtime Library has detected a fatal error in test.exe. Press Break to debug the program or Continue to terminate the program. And I'm not sure if I should trust the call-stack, but it looks something like: ... std::vector::end() std::vector::push_back() NameIndex::NameIndex() ... And heres some code-snppets of the NameIndex class, and how I'm calling push_back:
	struct NameIndex
	{
		NameIndex( const char* n="", int i=0 ) : name(n), index(i) {}
		std::string name;
		int         index;
	};
....
std::vector<NameIndex> m_Vector
....
m_Vector.push_back( NameIndex(szName,index) );

Any ideas on how to diagnose my problem?
Advertisement
i had the same problem some times. In both cases all I could do is disabling optimization at all. I think your std::vector doesn't cause the crash. it is bug of the compiler or linker. i'll be happy if i'm mistaking
Does it all work fine in a debug build? What version of visual studio do you have (Don't say VC6...)? Does it work if you compile a debug build but with optimisations on? Do you have any secure STL stuff #define'd out?
You could step into the assembly and compare what is going on.

You could also try turning off optimisation around specific parts of code using a #pragma to narrow it down.
I also have the exact same problem with my raytracer code (http://sourceforge.net/projects/raywatch). I haven't solved it, I use -O1 optimization; -O2 and above causes it to crash. In my case, it was to do with a static std::map the object factory uses. If the static std::map is removed, it works fine.

It simply crashes when compiled with MinGW 3.4.5 (on Windows). However, the code works fine even with full optimizations (-O3) when compiled with GCC 4.1.3 (on my Ubuntu Linux box).

So, I'm guessing it's nothing wrong with the code; just a compiler bug, which hopefully will get fixed with future versions.
Where does szName come from?
A few things to keep in mind are that without optimizations, data structures and stacks are often padded to try to detect errors like buffer overruns. It's possible that you might be getting the padding and not have the error detection on. Additionally, optimizations are made with single-threaded code in mind and you need give some hints when these assumptions are not valid. So, if you're using multi-threaded code, you may not have given the compiler or linker enough information to make the correct optimization. Ultimately, it's rarely the fault of the optimizer for code breaking when optimizing. What I mean by this is when your code breaks under optimizations, it's usually because you had a bug in your code that happened to fly by without optimizations; it's not usually a bug in the optimizer.
Thanks for all the replies.

Quote:Original post by Evil Steve
Does it all work fine in a debug build? What version of visual studio do you have (Don't say VC6...)? Does it work if you compile a debug build but with optimisations on? Do you have any secure STL stuff #define'd out?
Yes. 2005 Pro. Yes. Not that I'm aware.
Quote:Original post by Kylotan
You could step into the assembly and compare what is going on.
You could also try turning off optimisation around specific parts of code using a #pragma to narrow it down.
I'm not that proficient with assembly... I'll definately try some pragmas - I guess this is all I need to know?
Quote:Original post by Zahlman
Where does szName come from?
It's actually from a std::string, like this:
m_Vector.push_back( NameIndex(strName.c_str(),index) );
I did this because in some other places NameIndex's are constructed from legacy code, but I could just make these other pieces of code construct a temporary std::string and throw out my use of char* entirely...
Quote:Original post by Rydinare
Additionally, optimizations are made with single-threaded code in mind and you need give some hints when these assumptions are not valid. What I mean by this is when your code breaks under optimizations, it's usually because you had a bug in your code that happened to fly by without optimizations; it's not usually a bug in the optimizer.
This code is only run from one thread (other threads are used, but their outputs are buffered and retrieved by the main thread).
I hope it's a bug in my code (not the compiler), but I'm too dependent on debug builds for tracking down these kinds of bugs! :(
It's possible, but not likely, that a bug in the optimizer
produces a crash.

It's much more likely that you have a bug which is being manifest
due to the perturbations of the optimizer. Padding of structures
and initialization of variables are good candidates. Another gotcha
is that the compiler is allowed to change the order of side effects,
but only does so when optimizing. Ie: f(a(),b()), a() might be
called either before or after b() at the compiler's pleasure. Another
one I saw recently was calling a library function with the wrong number
of arguments (due to an incorrect header file) worked fine in the debug
version but crashed in a release version. C is full of such pitfalls.

---visit my game site http://www.boardspace.net - free online strategy games

Change const char *n in the constructor to const std::string &n, and don't use C strings unless some library gives you C strings (in which case, you'd want to wrap them in std::string ASAP before they get destroyed). You probably have some funky memory issues going on as Zahlman was onto.

This topic is closed to new replies.

Advertisement