Tuesday, November 14, 2006

Optimized Failures

Lemme complain about this freak bug of nature. Seriously, it's straight outta Mordor. It starts with attempting to debug a console game of Boggle. Essentially, Boggle is a word find game. So we display a 4x4 board of letters and then ask the user for a word. Well ... something along the line wasn't working. So we began to debug. It appeared that the failure was with string::getline(). Well, let's work with a more primitive type: char[]. "cin >> input" would fail. "cin.get(input,10)" would fail. WTF? Well we tried a random combination of words and it appeared that cin was neglecting to give the first four letters. Hmm? Maybe another cin was grabbing our input. So we commented out most of his code. No luck. Then more code. No luck. We commented out EVERYTHING but "char input[10]; cin.get(input, 10);" It still failed. So to check if anything came out, we initialized input to {0}. Turns out, the declaration itself was failing. It would initialize the last six characters to 0, but not the first four. Well, to be honest, that looks like something is screwing up the stack. Maybe it did allocate properly, but some piece of assembly was then using pointer arithmetic to mess up the char[]. Odd and unlikely, but seemingly possible. We then added some dynamic memory with "char* temp = new char[10]; if( temp ) int num=0; delete[] temp;" It appeared to be skipping the if check all together. The other lab aide thought it did the if check, but failed so it skipped to the delete. I don't think it even checked the if. It was like C++ was optimizing out the unnecessary code. Saying this triggered a response in the neighboring student. "Sounds like you're running in Release mode." Sure enough, we were debugging a program that was compiled in Release mode. I have no idea if that could screw up the stack, but the facts prove it didn't. Instead, it was our debugging tools: local and auto watches. Though it did initialize the full string and input the full string, the debugger was pulling the variables from the wrong location in the stack. The debugger was expecting something else on the stack that would generate a valid offset. However, in release mode, that random stackness was lacking, thus its offset was invalid. In hindsight, this may have been apparent that the original board, though seemingly broken in the debugger, output just fine. So all signs clearly point to the debugger instead of the code.

And now you know.

2 Comments:

At 10:52 PM, Blogger TT said...

So, is there an option in the debugger to recognize Release mode? Or does it just not work that way?

 
At 9:09 PM, Anonymous Anonymous said...

I don't know; it's Visual Studio

 

Post a Comment

<< Home