The trusty old bug has been the bane of software developers and engineers for more than 140 years. Yes, you read that right. It was in fact Thomas Edison that coined the term "bug" in the late 1870s. It appeared in many of his notebook entries where he describes for example that the incandescent lightbulb still had many "bugs left."
His efforts to debug his inventions are quite legendary. Consider the true grit and determination it took for a man already in his mid-sixties to work 112-hour working weeks. He and his seven-person team (it is a common misconception that there were only six because the seventh member didn't appear in the group photograph) became known as the insomnia squad during a 5-week stint that resulted in very little sleep.
These days, thanks to advances in technology, software developers have a vast array of debugging tools (inside and outside of Visual Studio) at their disposal. So does debugging really matter? Of course it does. It is part of what we as software developers do. If we don't debug, well, here are some examples:
Examples of software bugs affecting the lives of millions of people can be found all over the Internet. We're not simply talking about the run-of-the-mill bugs either. Sometimes we're faced with seemingly insurmountable issues. It is the comfort of knowing how to use some of the tools available that makes the difference between a stable application and one that is totally unusable.
As of writing this, IntelliTrace is only available in Visual Studio 2015 Enterprise. IntelliTrace is, however, not a new feature in Visual Studio. It has evolved over time, since Visual Studio 2010, into what we have available today.
Recipes.cs
file, you might need to add the following using
statements:using System.Diagnostics; using System.Reflection; using System.IO;
ErrorInception()
to the Recipes
class. Also, add the code to read the base path and assume that there is a folder called log
. Do not create this folder on your hard drive. We want an exception to be thrown. Lastly, add another method called LogException()
that does nothing:public static void ErrorInception() { string basepath = Path.GetDirectoryName (Assembly.GetEntryAssembly().Location); var full = Path.Combine(basepath, "log"); } private static void LogException(string message) { }
ErrorInception()
method after the full path has been determined. Here we are trying to open the log file. This is where the exception will occur:try { for (int i = 0; i <= 3; i++) { // do work File.Open($"{full}\log.txt", FileMode.Append); } } catch (Exception ex) { StackTrace st = new StackTrace(); StackFrame sf = st.GetFrame(0); MethodBase currentMethodName = sf.GetMethod(); ex.Data.Add("Date", DateTime.Now); LogException(ex.Message); }
public static void ErrorInception() { string basepath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); var full = Path.Combine(basepath, "log"); try { for (int i = 0; i <= 3; i++) { // do work File.Open($"{full}\log.txt", FileMode.Append); } } catch (Exception ex) { StackTrace st = new StackTrace(); StackFrame sf = st.GetFrame(0); MethodBase currentMethodName = sf.GetMethod(); ex.Data.Add("Date", DateTime.Now); LogException(ex.Message); } } private static void LogException(string message) { }
Program.cs
file, call the ErrorInception()
method. Right after that, do a Console.ReadLine()
so that our console application will pause there. Do not add any breakpoints anywhere to your code:ErrorInception(); Console.ReadLine();
Well now, with IntelliTrace and Historical Debugging, you just need to click on the Break All button:
So what is the takeaway here? If you only remember one thing, remember this. Once the users of your system lose faith in the abilities and potential of that system due to bugs, that confidence is almost impossible to regain. Even if you resurrect your system from the ashes, after it was laid low by bugs and other issues, to produce a flawless product, your users will not be easily swayed. This is because in their mind, the system is buggy.
I once had to take over a system partially developed by a senior developer who was leaving the company. She had an excellent specification and a well presented prototype shown to the customer. The only problem was that she left the company shortly after the system's phase one was implemented. When the bugs came popping up, the client naturally asked for her assistance.
Telling the client that the developer (who has been solely responsible for building a relationship with the client) has left the company did not bode well to instil a sense of confidence. Having a single developer involved was the first mistake of this particular project anyway.
Secondly, phase two was about to be developed by yours truly, who was also the only developer assigned to this client. This had to be done while building on top of the buggy phase one. So I was fixing bugs while developing new features for the system. Luckily this time round, I had a fantastic project manager called Rory Shelton as my wingman. Together we were dumped in the deep end and Rory did a fantastic job managing the client's expectations while being totally transparent with the client regarding the challenges we were facing.
The users were unfortunately already disillusioned with the provided system and didn't trust the software. This trust was never fully regained. If we had IntelliTrace and Historical Debugging back in 2007, I definitely would have been able to track down the issues in a code base that was unfamiliar to me.
Always debug your software. When you find no more bugs, debug it again. Then give the system to my mom (love you mom). You as the developer of that system know which buttons to click and what data to enter, and in which order things need to happen. My mom doesn't and I can assure you that a user unfamiliar with a system can break it quicker than you can brew a fresh cup of coffee.
Visual Studio provides developers with a very powerful and feature rich set of debugging tools. Use them.