Wednesday 2 June 2010
C++ bug hunting
I remember well my first experiences with computer programming. I was required to take a lab class on Maple as a freshman in college, and it was rather frustrating. I'm surprised my TA was still being civil to me after all the dumb questions I asked him all semester. I succeeded in "writing" a for loop (copied an example from the help files) for the final exam for that class, and considered that the triumph of my freshman year. I swore to myself I would not pick a branch of physics that would have me staring at a computer screen all day.
As the unromantic description of what I do at work all day is now "write computer code," I have eaten those words many times over. I have also, thankfully, gotten better at computer programming. I like it now; a lot of programming is like solving a logic puzzle. I can now claim a working relationship with C++ and SQL, a handful of successful encounters with Python, and an acquaintance with Java. I'm not a full-fledged programmer, but I can write code for my analysis.
Of course, that also means a lot of my time spent "researching" is spent researching why my code is not doing what I expected/planned on/ thought I told it to do.
The easiest problems to deal with are the compiler errors. After I write a piece of code, the compiler translates the human-readable program into a computer-readable set of instructions, which can then be run by the computer. Unless, of course, I wrote something the compiler cannot translate. Then it spits out error messages detailing, in compiler-speak, what it couldn't read and where to find it. This normally happens because I mistyped something or didn't provide some part of the program with quite the information it expected. This also barely counts as an error because these issues are normally fairly easy to fix. This is not what is meant by the term "debugging."
Of course, sometimes I mistype something in a way that still makes sense to my compiler. This often happens when I get variables names or other labels mixed up. Then the code will compile and execute just fine; it will just give me nonsense. I then get to spend a merry hour or two (or three days plus an hour going over code with my adviser) double-checking my variable names and trying to sort out where the insanity came from. This is also not what is meant by the term "debugging."
Debugging means getting rid of bugs, or a program's attempt to mess with memory inside the computer. Every computer divides its memory up into sections for different uses: one section for the operating system, one section for running programs to use, etc. A program can grab chunks of the free memory to store stuff like numbers and strings and objects and whatever else it needs to store while the program runs. When the program's done, it lets go off all that memory for the next program to use.
In C++, the programming language I primarily use, I have a lot of freedom to control how my program deals with memory. This also means I have a lot of freedom to mess up that memory. I could tell the computer to go grab some information from the wrong spot in memory, clobber old information by putting new information in the same spot, or try to pack more information in a space than I allocated for it. Sometimes, the computer will let me get away with this; there happened to be an integer where I told it to find an integer, so it gives me some random (to me) integer. Sometimes, though, this mismanagement of memory by a program can endanger memory needed by other parts of the computer. In that case, the computer kills the program before it can do anything nasty. This is called a segmentation fault, and whatever mis-programming caused the issue is the bug.
Bugs are annoying. You write the code, you compile the code, you sit back and relax for the computer to do its work, and instead of the answer you get a fatal error message. Then begins the tedious process of establishing what exactly caused the program to crash. My most common cause of seg-faulting is declaring a pointer but forgetting to instantiate the object itself, or in other words, telling the computer to use a collection of information stored in memory but never setting up the collection. At least when I've made this mistake, the program is going to fail at that point the very first time it gets to that spot every time I run it. That would be a predictable and locatable bug.
Because sometimes bugs seem to migrate. The basic structure of my code is often a loop, where I analyze events one after the other. Sometimes a bug will kill things in the first 10,000 iterations on one sample, but won't strike until after 2 million on another. Sometimes it will skip a sample all together. Then I must somehow pin down a moving target.
Such a bus afflicts my code right now. Wish me luck.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment