Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1368194 Posts in 64209 Topics- by 56151 Members - Latest Member: iestynne

October 23, 2019, 12:54:42 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The most remarkable bugs you've encountered
Pages: 1 [2]
Print
Author Topic: The most remarkable bugs you've encountered  (Read 1323 times)
qMopey
Level 5
*****


View Profile WWW
« Reply #20 on: March 09, 2019, 12:14:59 AM »

Clearly the earth is just made of worms and that’s why we see shifting geometric patterns  Corny Laugh
Logged
RoKabiumGames
Level 0
**



View Profile WWW
« Reply #21 on: May 01, 2019, 10:16:57 AM »

The most "horriblest" of bugs I've had to deal with was with a language called ProIV.

It's a high level 4GL, and it allowed you to call other programs and pass in/out parameters.

If you passed in a literal to a program, it was possible that if the program you called tried to pass back a value to that literal then it actually changed the literal value!

So after that happened, the value of 1 would not equal '1' any more, and lines like this:

myint = 6 + 1;
if (myint == 7) { print "the answer is 7"; }

Would never be true.

This was a nightmare, since it changed the literal for the whole application, not just the current program, until you logged out and back in.

It was very hard to find this bug, and understand what was happening, and we spent many hours wasting time on this.

The best part, the owning company actually argued that it was a 'feature' and not a bug. Sad
Logged

qMopey
Level 5
*****


View Profile WWW
« Reply #22 on: May 01, 2019, 11:39:52 AM »

So there’s this compiler bug. It’s a proprietary compiler for some proprietary hardware. The bug is if you pass a pointer as the third parameter, the pointer isn’t properly sent through the call when compiled to assembly. Workarounds include padding the third parameter with an unused int, or pass in a struct pointer containing many other pointers, and ensuring the struct pointer isn’t the third parameter.

Silly workarounds instead of spending time fixing the compiler bug  Shrug
Logged
ThemsAllTook
Global Moderator
Level 10
******



View Profile WWW
« Reply #23 on: May 14, 2019, 08:24:10 AM »

Here's a small one I just had: In some UI code, I was doing hit detection for a list of items by subtracting the click position from the top of the list, dividing by row height, and storing the result in an unsigned int. I relied on the value underflowing to detect when I had clicked above the top of the list; as in, assigning a negative number to an unsigned integer and expecting to get a large positive number. I just built my game for Android, and found that tapping above the list was acting like I was tapping the first row. It looks like on ARM, assigning a negative number to an unsigned int truncates to 0 instead of underflowing to a large value. Weird! Seems like this could cause a lot of subtle bugs, so I'll have to watch out for it in other places.
Logged

ProgramGamer
Administrator
Level 10
******


The programmer of games


View Profile
« Reply #24 on: May 14, 2019, 08:43:05 AM »

@qMopey
To be clear, were the workarounds provided by the compiler vendors? If so, that's some advanced avoidance to fix the actual issue.

@ThemsAllTook
Yeah, relying on underflow for that seems like not a great idea, no offense. using a signed int and checking for a negative value would achieve the same thing, no?

In any case, it's interesting that underflow truncates your number, but I bet the compiler happens to be doing that for you instead of it being a platform thing. It seems really weird to me that it would be impossible to get an underflow on ARM.
Logged

ThemsAllTook
Global Moderator
Level 10
******



View Profile WWW
« Reply #25 on: May 14, 2019, 10:18:45 AM »

Yeah, relying on underflow for that seems like not a great idea, no offense.

If it's known reliable behavior, there's no reason not to use it. It either works or it doesn't. I find it important as a programmer to keep a clear picture of how my tools function and to use them as appropriate, intentionally avoiding dogmatic concepts like "probably shouldn't rely on this, but don't know why".

using a signed int and checking for a negative value would achieve the same thing, no?

Kinda. That's what I ended up doing. The reason it wouldn't be my first choice is because I'm comparing the row index with an unsigned value, which means 1) I have to explicitly cast when comparing to avoid compiler warnings, and 2) it opens me up to another category of problem due to cutting the positive numeric range in half. In practice, I'm obviously not going to have 2147483648+ rows in this list, but it's still important to keep in mind.

I'll have to dig into this deeper later today. I have a hunch that this is happening because I'm converting from float to unsigned int, and if I added an intermediate conversion via signed int, I'd still get the underflow. Both outcomes are perfectly reasonable; it's just interesting that ARM makes one decision while x86 makes the opposite one.
Logged

ProgramGamer
Administrator
Level 10
******


The programmer of games


View Profile
« Reply #26 on: May 14, 2019, 11:37:42 AM »

Well, I wasn't thinking about it in terms of dogmatic "shouldn't do this" principles haha, I just thought that checking for a large number after a subtraction sounds less exact than using a signed integer and checking if it's negative. Plus, yeah, converting between signed and unsigned is probably not a big issue if they represent a quantity of UI elements Wink

Do post again with your findings though, I kinda wanna know why the behavior is different too!
Logged

Schrompf
Level 6
*

C++ professional, game dev sparetime


View Profile WWW
« Reply #27 on: May 14, 2019, 10:58:29 PM »

My bet is on "Compiler optimisation exploiting some corner case or UB in the conversion chain". ARM is two-complements just like every other CPU architecture under the sun, the CPU definitely doesn't saturate a signed integer.

[edit] The more I think about it: maybe ARM64 has a specific FloatToUnsignedInt conversion instruction that x86 doesn't have. That one might indeed truncate.
Logged

Snake World, multiplayer worm eats stuff and grows DevLog
bateleur
Level 10
*****



View Profile
« Reply #28 on: May 14, 2019, 11:51:06 PM »

Only just discovered this thread, so time to share my all-time favourite bug from 35 years of programming!

The Winding Number Bug

A friend and I had programmed a multiplayer Bomberman variant on the Amiga. It was basically done and we were testing it, but we noticed that occasionally the game would crash. Trying to work out why, we systematically tested every feature and nothing crashed. We left the game running for hours and it didn't crash. We played it for hours... and it repeatedly crashed.

Eventually, I became aware of a pattern to the crashes. If I placed a bomb, then ran around the wall tile up and right of my position, when the bomb exploded the game would crash. So presumably if I just ran up and right one space that would do it? Nope, I had to run around the tile. Up-down-up-down? Nope. What if I went up-down-up-right-right (to make the distance the same)? Nope. How about around the block to the left? Yup, crash!

We looked at each other in confusion. The crash clearly depended on the winding number around the block. That is: it was measuring whether the character's path wrapped around the wall tile or not. But this was clearly impossible! Nothing in the code had the potential to calculate this, never mind crash after doing so!

Eventually we tracked down what was going on. The game used a kind of primitive homebrew object orientation to handle tile behaviour. The way it worked is that the code number of a tile was used to look up its behaviours. Due to a typo, one of the frames of the bomb flame animation had the same object code as the teleporter tile. The crash was being caused by a character moving onto the space above a bomb explosion flame. This was because the other end of the not-really-a-teleporter couldn't be found by the game. However, the character had to arrive at exactly the right frame for this to happen, because teleportation was only checked on arrival, not when standing still.

So why the winding number effect? Well, because of the way movement in the game worked, an experienced player could buffer each move a few frames ahead (while the animation for the last thing was completing). So, if you dropped a bomb then walked around the adjacent wall tile you could quite easily do it frame perfectly... and if you did you'd arrive on exactly the right frame to trigger the not-a-teleporter bug via the flames from the bomb you'd dropped. Mystery solved!
Logged

Pages: 1 [2]
Print
Jump to:  

Theme orange-lt created by panic