Programmers: Your weirdest bug stories

This thread is for stories of bugs you’ve created or fixed that were particularly funny, interesting, or memorable, for whatever reason.
Mine is as follows: About 7 years back, I was working on Battletanx: Global Assault for the Nintendo 64. We had a weird recurrent bug where every vague once in a while, something would go wrong in the collision/physics system, and the tank wouldn’t properly run into walls, wouldn’t fit through gates, etc. For quite a while, we thought that the collision boxes in the world had gotten messed up, but eventually we figured out it was something with the tank.

Debugging this was VERY hard because it would almost never happen, so we couldn’t just sit down, reproduce it, and start going. Finally, it started happening on a system with a debugger attached, and after much poking around, we realized that the tank’s collision box was messed up. In fact, it was rotated around by 90 degrees, so that the collision system thought the tank was wider than it was long (instead of the other way around). How did this happen?

So we started grepping through all of our code, looking for places that collision boxes got rotated, and we did find one interesting thing, which is that when immovable buildings were put into the world, if they were axis aligned (that is, at 0, 90, 180, or 270 degrees rotation) they would be rotated around to 0 degrees, with their width and height swapped around respectively. But that only applied to immovable buildings, not tanks, right?

But wait! One of the features our tank had was a teleporter powerup. And the way the teleporter worked was that it would first find a spot to teleport to, because you don’t want to appear in the middle of a wall. Then it would reserve that space, so that no one could drive into it in the middle of the teleportation (which took a few seconds). But how did it reserve that space? By moving the tank’s collision box there, and TEMPORARILY MAKING IT INTO AN IMMOVABLE BUILDING. So, whenever we teleported the tank, we would pick a random heading for it, which was a int16, and if that int16 happened to be precisely 16K or 48K, our collision system would screw up the tank’s collision box. But of course, there was no immediate or obvious link to the teleporting, and it only happened very occasionally. That was nasty.

We also had a relatively mundane bug in which our list of models would get randomly shuffled, resulting in driving buildings around and firing trees instead of driving tanks and firing bullets. That was so neat looking that we stuck it in as an easter egg.

Hang on - so this bug would only show itself if a random sixteen bit integer just happened to be either sixteen thousand or forty-eight thousand? If I’m reading that right, that is one nasty, evil bug.

I have two stories to relate on this, but neither happened to me, but to friends of mine. I’m a CS student, and this was back in first year, so this isn’t exactly hardcore stuff, but amusing nonetheless. Firstly, there was the fine effort of getting gcc (the compiler) into an infinite loop. In retrospect, there was only one thing it could really have been: turns out that the programmer in question had mistyped a very important ‘h’ as a ‘c’, and instead of including a header file in a source file, they had included the source file in itself. Tut.

The other one was someone doing a lab exercise, which was lucky, because only an hour of work got destroyed. For this to make sense, you’ve got to be vaguely familiar with the vi text editor. So, after making some seemingly innocent changes to the source file in question, this poor person’s code suddenly goes from a clean compile to generating a ludicrous amount of errors and warnings (I think the tally was roughly 116, but I could be wrong) for such a small program (probably only a few hundred lines). After a certain amount of detective work, the situation was explained. Earlier in that editing session, the person had begun typing accidentally without putting vi into insert mode first. For those that don’t know vi, not being in insert mode means that instead of the keyboard typing stuff, it is responsible for all sorts of commands and shortcuts. So when you start typing, a bunch of crazy random stuff starts happening, and you quickly stop, go into insert mode, and hope thing haven’t been too catastrophically affected by what you just did. As it turns out, on this particular occasion, my friend had managed to delete all instances of the letter n from his source code. He didn’t realise the mistake until he had saved and compiled the stuff, so it basically got thrown out. As I say, I’m glad it happened in a lab and not for something larger or more important.

As an aside: Was the N64 as difficult to program for as everyone said it was?

~ Isaac

Damn, that’s funny.

Being just a fledging programmer myself, the worst bug I had is an endless loop in such a manner to make it look like it wasn’t running at all.

:: sigh :: fledgling programmer

One of my programs for college was a little database. For extra credit I put it linked both directions and all fields, with tons of indexes and fun stuff. I wrote it modular and each module worked perfectly. but the whole thing wouldn’t work at all. I kept tinkering and twisting but the damn thing never worked as a whole. I had all my CS friends look at it but no luck. I had every TA and grad student I knew take a stab, and no good. Finally I got my prof to work on it and he couldn’t figure it out. He passed it to all his prof friends and industry contacts and they couldn’t figure it where it was wrong. Finally someone had the brilliant idea to compile it, rather than just debuging from a look at the code. and it worked. It went back through the ranks and it worked for some people, and not for others.

Never did figure it out. It worked on certain compilers on certain OSes but not on others. Something I did with the links really screwed with the computers, even though it was perfectly correct syntax and algorythym, and shouldn’t have had a problem.
ANSI standards my ass :mad:

MaxTheVool - You worked on one of my favorite N64 games! Are you still in the gaming industry?

I am not a programmer, I fix stuff, but I have found/seen some interesting bugs in software.

In a beta version of AOL (5.0, I think, could have been 4.0) all of the sudden the affected computer wouldn’t recognize the hard drive when it was rebooted. It turns out that if you followed a certain long series of steps it would (somehow) go into the BIOS and change the disk geometry. A friend of mine found it (AOL pulled good techs off the floor and had them try and figure out the steps to recreate it). I didn’t believe it until I did it myself. I am still not sure how in the heck it changed BIOS settings. On the bright side the fix was easy. You just had to have the BIOS redetect the HD or manually enter the settings and all was well. At the same time walking users through the bios isn’t much fun.

At Intuit, version 5 of Quicken had a nasty little bug. Quicken has user defined categories for budgeting purposes. For example you might have Household as a category with rent, electric and gas as sub-categories. In the first couple of versions of Quicken 5 if you deleted a category then merged the remaining sub-categories into another category it would absolutely hose the data file. The data file was so hosed that you couldn’t even open it. There was no fix once the file was damaged as the data recovery tools couldn’t even read the file. It was ugly. My training class found and reported this bug. Then I experienced the joy of telling people with no backups that they had to reenter all their data. I found a ton of bugs at Intuit. They named them after the person who found it and I got up to like 7 in my name, which is a lot for a tech to find in a ‘gold’ version of software. Most of them were the annoying kind where a reinstall would solve the problem.

At my present job I have found a couple but none are that big of a deal.

Slee

I don’t remember it being particularly difficult, no. Although I missed the first couple of months of the first N64 project, during which our basic engine was written, so I probably missed the fun part with the task scheduler and all.

Hey, a fan! :slight_smile:

Yeah, I’m at capcom now, after the ultimate demise of the struggling 3DO company. (I also worked on the first Battletanx, the first Army Man, and the underappreciated WDL:Thundertanx for the PS2)

Not a bug story, per se. But horrifying.

I’ve recently been given a GIANT bunch of real-time code to maintain. It’s been exhibiting wierd problems, and the original coder has fled the company (good thing for him). It’s written in C.

It’s roughly 100,000 lines and EVERY SINGLE VARIABLE IS GLOBAL!!! Extern’d… every one of 'em. There are about 150 functions in all and NOT A SINGLE ONE OF THEM RETURNS ANYTHING!! NOR ARE ANY ARGUMENTS PASSED! The code deals with a finite number of objects, each of which has 50 or so related parameters which must be kept up with. You guessed it… there are FIFTY DIFFERENT ARRAYS! Not one single structure in the entire mess! Apparently this “coder” was bitten by a pointer as a child. No pointers. Not a single one. Just arrays and indices.

A final note (programmers brace yourselves). Somewhere in the development of this quagmire, he discovered that all his arrays were off-by-one. Rather than adjust the aforementioned global index(es); This genius ran a find/replace on the entire directory replacing every array reference with this: var = random_array[global_index - 1];

That’s right. It does math to get every single array index now. Even in 100+ loops.

I need a beer.

This was about 12 years ago, so I may have some of the details wrong.

I used to program for a small company that wrote add-ins to QuarkXPress on the Mac. There’s some oddity about registers when doing that (A4 vs A5 IIRC). Anyway, I had a consistent problem with a certain function causing the entire display to explode into random colored flashing pixels. After a fair amount of tracing and debugging using MACSBUGS, we finally discovered that one of my pointers was getting reset to 0x00000000. I would then offset into the pointer and was apparently overwriting big chunks of the video driver. We finally fixed it, but the effect was so cool we kept the code as a practical joke for a while. We would insert it into the code of new programmers and then watch them trace it down. Fun for all!

STUPID ITALIAN BOOT ROMS!

(It’s not really my programming, but I think it’s funny.)

I was working for a college where the computer labs ran on Novell networks. Each PC’s network card had a ROM chip installed to let it boot from the network server, so the machines had no need for a hard drive. We used McAfee’s virus checker with no problems for a couple of years. Then we downloaded and installed the latest virus definition files, and several of our labs started reporting the Italy virus on every single machine! Other labs came up clean. It took us quite a while to figure out that the ‘infection’ was a scrap of code in the boot ROMs on one batch of network cards. McAfee was amused, and fixed it a week or two after we sent in the report.

A couple from college days.

I was hired as a student programmer by the college. We were working in COBOL on a DEC-10 back in 1976-77. No DBMS, just a well-defined ISAM file structure. Well, almost.

As part of the registration process, each student got a record for each class written into the classes file. If there was a glitch or a conflict or a class became unavailable, they would have to “unregister” and then go back through the process with new classes. The chief designer determined (for some reason) that we would NOT physically delete unregistered records, but simply set a deleted flag within the record. I wrote the unregister procedure that way and all went well during the registration process. However, at the end of the semester, the guy that had written the GPA calculation module did not look at the deleted flag and we would up sending out about 750 Sco-Pro notices to people who had passed all their courses. You see, a grade didn’t get posted to the “deleted” records, so the GPA calculations treated it as an F…

The next semester, we changed the unregister module to physically delete the records.

The other glitch was one that I found and exploited greatly to my own advantage for a while. In the Fortran compiler on the DEC-10, one could assign external devices. This included the dumb terminals, identified as TTYnn. I wrote a program that would grab an unattached dumb terminal, assign it and display a bogus login prompt. It would then capture the user id and password, write it to a file, then exit after displaying the invalid login message. The regular prompt would then come up, they would re-enter their login and connect, and simply think that they had mis-typed their password or something.

We would then log in as them and play Super Star Trek until their account timed out. This was considered great fun back then, mind you. However, I wrote it up as part of a paper that I did on computer security my senior year. We wound up reporting it to DEC and they patched the operating system to not allow that any more unless you had admin privileges.

I am a PowerBuilder programmer. I know. The Horror. Anyway, as wonderful as this environment is, it is not without its quirks. There was one bug I had that occurred sporadically but had devastating consequences to the data connection when it did occur. It turned out that the constructor code for an ancestor object would not be executed randomly, despite the fact that PB event code is supposed to execute from the ancestor down (or up, whatever.) it was easy to fix once I found it but what a pain in the ass.

I’m not a coder, really, not on this job. Who knows why, since I have more coding experience than most of the people who are programming. Anyway…

At my previous job, we had several ‘modules’ working together on several different systems. One of these kept freezing up after doing one task, using up 100% CPU and just sitting there. No memory leak, at least. As it had suddenly started doing it, we weren’t sure what the problem was, and were auditing all our libraries and such.

Finally, we found the problem in the most obvious of places, the source for that particular module. In between various functional coding and well-commented material, we foind the line:

But see, that wasn’t the funniest part. We had a CVS archive set up to keep track of every change, and who submit it. So we searched through the diff files, found the place where that line was added, and it was done by one of our better coders. CVS allows comments to be added to each revision of the code. The comment for that particular change?

Stylistic Improvements.

Needless to say, he never lived that moment down :wink:

I’m not a coder, really, not on this job. Who knows why, since I have more coding experience than most of the people who are programming. Anyway…

At my previous job, we had several ‘modules’ working together on several different systems. One of these kept freezing up after doing one task, using up 100% CPU and just sitting there. No memory leak, at least. As it had suddenly started doing it, we weren’t sure what the problem was, and were auditing all our libraries and such.

Finally, we found the problem in the most obvious of places, the source for that particular module. In between various functional coding and well-commented material, we foind the line:

But see, that wasn’t the funniest part. We had a CVS archive set up to keep track of every change, and who submit it. So we searched through the diff files, found the place where that line was added, and it was done by one of our better coders. CVS allows comments to be added to each revision of the code. The comment for that particular change?

Stylistic Improvements.

Needless to say, he never lived that moment down :wink:

This is an interesting one I found once;

int x[100];
int i;

for (i = 0; i <= 100; i++)
{
x* = 0;
}

On an Microsoft compiler, on a PC, this loop never exits.

Why, because on the 101st iteration, the boundary of x is overwritten to the next location, which happens to be i, which sets the loop back to 0.

Are you sure that code was originally written in C? This sounds like the sort of thing f2c might give you.

This wasn’t really a bug, but kind of a funny story. I was working with an asynch device and I wanted it to force a hardware interrupt periodically so I could see if there were any characters laying around in the hardware buffer. I thought, what the hell, the interrupt bit is read-only, but maybe if I toggle it, it will force an interrupt. Yes!!! It worked!!!

So I go ahead with my program and read what’s stored in the hardware buffer. It said …

Don’t f*ck with me.

:smiley:

I love “professional” bugs.

Mid 1970s. (Story inherited from the programmer to whom it happened. I was not coding yet.) When executing a sort, COBOL uses two possible methods of handling the input and output files. In one method, the input and the output are directed to specific routines where one can perform editing, formatting, etc. In the other, COBOL allows a shortcut where the extra editing is ignored, so that you can pre-sort the input file by specifyng “USING filename” or can take the edited data and simply produce a sorted file by specifying “GIVING filename.” This programmer had an application where he did not need to perform any input edits, but he needed the file re-sorted, so he began the program with “SORT file ON ASCENDING KEY whatever USING FILEA” The program simply went to hell on him. No one in the shop could figure out what the problem was, (the USING and GIVING options are pretty rare, since one usually needs to do some data manipulation.) Finally, he coded a work around to get it into production. (Heavy duty work around: Input procedure: Open file, read file, release to sort, at end close file.) Then he notified Burroughs that they appeared to have a bug. Burroughs’s response was to say that it was a known bug and they had never figured out the problem. They were amazed to find that he had found a way around it!

Late 1980s: ASI (a firm that produced fairly decent statistical analysis programs) puts out a new release that will change the key on their central file. Basically, they were adding two to six bytes to each field so that the key would be large enough to handle future expansion. Several hundred programs are involved in the change, so they send out a conversion program so that each customer can simply run their data through the converter and have a working system on the other end. Unfortunately, the conversion program used a COBOL “group move” to move the key data. In COBOL, this means that one can grab a series of fields under a single name and execute a single move rather than moving each field individually. Of course, this meant that the first key field, that had expanded from six to eight bytes now contained the first two bytes of the second field. The second field, that had expanded from eight to twelve bytes, while missing the first two bytes of data, now contained six bytes of data from the third field, and so on.
As a boneheaded move by a kid coder, this was not the worst problem in the world. As the (hypothetically) checked and tested conversion program that was sent to a large number of multi-million dollar corporations to reformat their production data, this was among the stupider I have seen. They literally could not have tested this code before they shipped it.
Of course, ASI did not have a monopoly on idiots. At the shop I was working, the senior analyst (with 20+ years of experience) decided that he could trust the vendor, so he went ahead and installed the update and converted the production files, live, without ever performing his own test.

My favorite horror story was the following (in miniature):



int i = 4;
printf(broken(i));   //prints nothing
printf(fixed(i));   //prints "Luvley luvley"
exit();

String broken(int i) {
   String result = "";

   if (i == 0) {
      result = "No dice";
   }
   else if (i == 1) {
      result = "No dice";
   }
   else if (i == 2) {
      result = "No dice";
   }
   else if (i == 3) {
      result = "No dice";
   }
   else if (i == 4) {
      result = "Luvley luvley";
   }

   return result;
}

String fixed(int i) {
   String result = "";

   if (i == 4) {
      result = "Luvley luvley";
   }
   else if (i == 0) {
      result = "No dice";
   }
   else if (i == 1) {
      result = "No dice";
   }
   else if (i == 2) {
      result = "No dice";
   }
   else if (i == 3) {
      result = "No dice";
   }

   return result;
}


This is one of the reasons that Java VMs still does not create a “build once run everywhere” solution. You’re still at the mercy of whoever made the VM.

Course then you start coding assembler and are still at the mercy of whoever put together the hardware…