   Tips & Tricks: Fixing Bugs in Existing Programs
  HelloI was looking for advice & tips on fixing bugs & updating in programs.See I am going through this kind of thing now with my Win32 C++ Graph Drawing Application. And I have found that the X axis & Y axis are not always drawn in the correct position(bug) & I want to add new things to do with WM_MOUSEMOVE to the application. But its really becoming a nightmare because in both cases I am torn between trying to change the existing functions/code to fix the bug or to dump a whole series of functions/code & rewrite it all.So I am looking for advice on: - When you have a bug at what point do you decide to alter the existing code to fix it OR Start again & rewrite the majority of functions associated with the bug? (Do you decide this case by case, what tips & tricks do you use?)- When you first design & make your code, do you break your program actions up into TINY actions & make each action a function? Then if you have a bug it maybe easier? - I guess in work you must have had to fix some annoying bugs, what is your method, tips & tricks to making life easy?- Maybe some tips might be:Example; program crashes when I click a button but I have no idea why:   - Identify the action where the crash occurs   - Identify all functions assoiated with that action   - Identify which function the error occurs in   - Isolate the variables to determine exactly where the bug occurs (line)   - Determine why the error occurs   - .... Rewrite whole function?   - ... ?   
  Put a breakpoint at the earliest possible place after the action I know causes a crash, in your case right in the button-click handler. Then step through until it crashes. Next time, step further in, repeat as necessary, until I know where it crashes. Try to figure out why.Gradually improve the structure of your code, including in the process of fixing bugs. Avoid rewriting, especially in response to bugs, but don't be afraid to reorganize. Avoid adding new features in the process, because you're likely to just get confused. Hopefully someone with more experience can clarify exactly how much of that was nonsense.   ;  In the case of a crash you might be lucky: If the call stack dump is right you are pointed to the exact location in your code.And like theOcelot said, an interactive debugger is not only handy for locating bugs but also for writing new code. Make sure you got a good grasp of what your debugger can do, since navigating your control flow is just one feature. A decent debugger can inspect variables for instance. Also check if you can do conditional breakpoints. They can be handy if you expect a bug to occur late in loop - and you don't want to manually step through the first zillion loop cycles by hand. Defining temporary helper variables is also an option.Unfortunately an interactive debugger is not always an option or the quickest way to success, if your application runs in an environment without a debugger (or was built without debug information) or if the very nature of your app corrupts the idea of breaking the program flow. The latter is especially the case in interactive applications. In both cases you can only resort to logging or some other human-readable feedback. For locating crashes and the like this reduces to the "I'm here" logic (PseudoCode):Print("I started.");DoSomeStuff();Print("Did some stuff.");DoOtherStuff();Print("Other stuff done, too.");DereferenceNullPointer(); // <- some access violationPrint("Am I still alive?");The last line will never be printed to your console/logfile. Make sure your logger has a flushing logic or else you might be pointed to the wrong line.For reorganizing or even creating new code have a look at Unit testing. This will greatly reduce the need to do the above - somewhat tedious - work. Though: Keep in mind that writing tests is not easy. First, writing a test for a particular component can likely take longer than writing the component itself. And second a test can also be buggy (false positives). And not everything can be (automatically) tested.Personally I use a mixture of logging and testing: I setup a calculation and check its result, but also dump to a Html some intermediate steps and occasionally generate images and charts (I do some graphics and dumping geometric stuff in bare numbers is not human readable).;Quote:Original post by gretty- When you have a bug at what point do you decide to alter the existing code to fix it OR Start again & rewrite the majority of functions associated with the bug? (Do you decide this case by case, what tips & tricks do you use?)Personally, I divide code rewrites and bugfixes into entirely different categories of work. If I have a bug, I fix it. If, in the process of fixing the bug, I notice that the code could use a rewrite, I might do so - but only after the bug is fixed. Ideally, the bug fix should be committed to a version control system so I have a known valid version of the code before I undertake a rewrite of anything.I also split feature addition into its own category in a similar way. Mixing these tasks is just asking for trouble, because it's all too easy to introduce or complicate existing bugs when adding features, and so on.Quote:- When you first design & make your code, do you break your program actions up into TINY actions & make each action a function? Then if you have a bug it maybe easier? Yes, although it depends on how you define "tiny." This is something that takes a lot of experience to gauge well; these days I find myself splitting things into functions more or less off the bat, whereas earlier in my programming career I would often write things one way and then split out functions several times after the fact.I wouldn't worry about getting things right the first time; that's a skill you can only develop with a lot of experience. Instead, get it working right first, then get it pretty. (Then, optionally, get it fast - but only if it needs to be fast.)Quote:- I guess in work you must have had to fix some annoying bugs, what is your method, tips & tricks to making life easy?Reduce the amount of code you have to debug. For instance, if you're chasing a rogue crash, comment out the second half of your game loop, or whatever; just do something that removes a big chunk of executing code. If the crash goes away, you know the cause is isolated to the code you commented out. Then you can look in that code, comment out large blocks of that, and repeat the process recursively until you narrow down the cause.Logging is a tremendous tool, as unbird noted. So is a debugger, as he also noted. If you're using MSVC especially you owe it to yourself to explore the features of the debugger. Don't be scared of things that seem mysterious or cryptic; you can learn a hell of a lot about programming from just checking out features in the debugger and then doing some research on what they're for. Knowing your toolkit well will make you a much better developer. (If, on the flip side, you're condemned to using GDB, then you have my deepest sympathies.)Lastly, code organization can make a big difference when it comes to ease of debugging. If you write code that is easy to unit-test, then it's inherently easier to debug, because you can automatically test if the code is working correctly, and pin-point where it is failing based on which unit tests don't pass. Again this is something you'll develop an instinct for over time, but don't be afraid to rewrite code a few times to make it amenable to unit testing. Good testable code is reusable code, and investing in good reusable code will make your life easier down the road.Overall, one of the most important things I learned as a new programmer was to not be afraid of rewriting things that don't work, or aren't optimal. Once things are running it's tempting to treat them like they're etched in stone, and never change them again. This isn't necessarily bad per se, but it prevents you from making improvements to your code; in turn, that inhibits the development of your instincts. Once you've written a lot of clean code the hard way, you'll be better prepared to write it cleanly the first time around in new projects.If you aren't already, you owe it to yourself to use a version control system. This makes it practical to experiment with different rewrites and potential bug fixes. Want to make a major change, but unsure if it will actually improve your code structure? Fork a branch in your VCS, make the changes, and then do a comparison to see which result you like best. If the new code is superior, merge the branch back into the trunk and you're golden. Otherwise, just shelve the branch and move on. This applies equally to bug hunting, especially for those nasty, subtle bugs that take a lot of effort to pin down.Finally, take notes. If you find a good trick or technique during a bug hunt or rewrite or whatever, write it down. When you get stuck on something, read through your notes, and see if anything offers inspiration. Over time this will, like many other things, just blend into your programming instincts - but especially while learning it can make your life a heck of a lot easier.   