Digital Edition

SYS-CON.TV
Reflections on Debugging
Matching problem patterns to past issues

This rather pedagogically worded article is a collection of my thoughts on debugging Java software, the programming patterns I have used, some useful APIs, and techniques.

What it is not - it's definitely not complete in terms of information on debugging, its techniques, styles, etc. It's primarily a list of things that have worked for me time and again and a few tools that I keep in my toolkit to use when the situation demands it. I think they will be of use to you as well.

I have been fortunate to work in environments where I touched upon various facets of Java, used various APIs, and generally did extremely satisfying work. In all these years, debugging has stood out as an activity that everybody has to perform almost as much as they code or design. I have noticed time and again that being able to debug well is an extremely useful skill. It can be learned over time and honed and it is, to a large extent, the ability to match problem patterns to past issues. People like Rajiv (www.me.umn.edu/%7Eshivane/blogs/cafefeed/) can uncannily pinpoint a problem's cause when they hear its description. This ability comes from years of experience and the intent to learn from every new debugging experience.

Debugging
Debugging is the act of locating and fixing a flaw in software. A flaw can manifest itself in multiple ways. Sometimes it's apparent, for example, when the program crashes or does not do the intended action or does not return the intended result. Sometimes it is hard to say what's wrong when a program does not return, the CPU keeps processing something, or when the program does something unexpected in addition to the right action. Debugging, of course, is the action we take post having seen a flaw.

Isolating the Problem to Code: Identifying Where to Look for a Problem
The problem or flaw appears as a failure of the software to do something it should have. When you encounter a flaw, to debug it you need to form a mental model of the code to identify where the code is that failed. Debugging largely follows the process of elimination and this process is helped by any symptoms that you can find.

When you have the piece of code that failed, you try and find the cause by asking and answering questions - what is occurring? What possible causes could result in this problem? For example, if something should have happened and it didn't, perhaps the code was not reached. Why would the code not be reached? Maybe the if condition under which the method gets called did not evaluate to true or perhaps the if (something != null) check was called when something had the value null.

Another example: if there is an exception, then there is additional information about the location of failure and the steps that led to it. The type of exception will tell you the nature of failure. So if you see a ConcurrentModificationException thrown by an Iterator's next() method, you will have to:

  1. Find out under what conditions this happens.
  2. How could these conditions have been created in your program?
  3. Maybe you removed something using list.remove() in your loop, or perhaps you passed reference to the list to some other thread that is modifying it.
Once you have a mental picture of the surroundings of the problem and why it might be occurring, it's a matter of eliminating the reasons one by one starting from the most likely cause.

Even if you intend to use a debugger, this is a necessary step. You have to always backtrack mentally from the point of failure to locate all possible causes of failure. A lot of debugging skill relies on this one ability alone.

Reading an Exception
Java Exceptions have a lot of information in them and should be well understood to debug problems. Often, I've noticed programmers use the following template for exceptions.

try {
// do stuff here
} catch(Exception ex) {
System.out.println(ex);
}

If you wish to print the exception to know when a problem has occurred, you must consider using ex.printStackTrace(). There are multiple advantages:

  • When using System.out.println(ex), several times no message is prin-ted other than the class name of the exception that occurred. Imagine having this piece of code in multiple locations; how will you ever know which catch handler printed java.lang.NullPointerException?
  • An exception when printed stands out in a log file or the console. It's several lines long and just the pattern of an exception stack trace print is so different from the other message; it's much easier to find than an exception message that looks like other logging statements.
  • Following JDK1.4, chained exceptions get printed as well and you don't have to manage them manually. Root cause gets carried along with the exception.
  • Last and most important, the stack trace contains a wealth of information that can be used to create a mental picture of what happened.
There have been lots of times when I have looked at a stack trace and said: it should not have come here and been able to trace the problem to a wrong check in an earlier part of the code. You must know how to read an exception. Here's a Java exception printed out.

: Output generated by System.out.println() :
java.lang.ArrayIndexOutOfBoundsException: 0

: Output generated by ex.printStackTrace() :
java.lang.ArrayIndexOutOfBoundsException: 0
at com.sonicsw.tools.test.ThrowException.processArgs(ThrowException.java:32)
at com.sonicsw.tools.test.ThrowException.main(ThrowException.java:21)

1.  java.lang.ArrayIndexOutOfBounds-Exception: 0
The first part of printStackTrace is to do a print out of the exception similar to the System.out.println, so already you've gotten that for free. This part of the exception stack trace is formatted according to the type of exception, and the information printed varies from exception to exception. Some exceptions print nothing more than the class of the exception. Some exceptions (specially custom ones) print a lot of context information that led to this exception.

2.  at com.sonicsw.tools.test.ThrowException.processArgs(ThrowException.java:32)
The rest of the exception is the stack trace starting with the location that threw the exception at the top, and the caller of the method in which the exception was thrown below it, and so on until the executing thread's run method or the main method. The information provided on this line consists of:

  • The fully qualified class name: com.sonicsw.tools.test.ThrowException
  • The method: processArgs
  • The file: ThrowException.java
  • Line number: 32
About Sachin Hejip
Sachin Hejip, an architect with Sonic Software, is currently part of Sonic's ESB tooling intiative where he is leading a team of engineers develop Eclipse plug-ins to take Sonic ESB development to the next level. A recipient of Pramati's highest award for technical excellence, the Pramati Fellowship, he has been a core member of the Pramati engineering team where he led the Web Server intiative and has been a key member of the Pramati Studio R&D team. He has a keen interest in development tools and was the architect of the IDE's parser framework, which formed the base of his implementation of the code completion and Java/J2EE Refactoring tool set. He has designed and developed Pramati's paradigm of J2EE development called "Express Development" including the server-agnostic deployment framework.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1



ADS BY GOOGLE
Subscribe to the World's Most Powerful Newsletters

ADS BY GOOGLE

The question before companies today is not whether to become intelligent, it’s a question of how and...
While some developers care passionately about how data centers and clouds are architected, for most,...
ChatOps is an emerging topic that has led to the wide availability of integrations between group cha...
As DevOps methodologies expand their reach across the enterprise, organizations face the daunting ch...
As Marc Andreessen says software is eating the world. Everything is rapidly moving toward being soft...
You know you need the cloud, but you’re hesitant to simply dump everything at Amazon since you know ...
Is advanced scheduling in Kubernetes achievable?Yes, however, how do you properly accommodate every ...
The cloud era has reached the stage where it is no longer a question of whether a company should mig...
The need for greater agility and scalability necessitated the digital transformation in the form of ...
In his keynote at 18th Cloud Expo, Andrew Keys, Co-Founder of ConsenSys Enterprise, provided an over...
Coca-Cola’s Google powered digital signage system lays the groundwork for a more valuable connection...
In his session at 21st Cloud Expo, Raju Shreewastava, founder of Big Data Trunk, provided a fun and ...
"Since we launched LinuxONE we learned a lot from our customers. More than anything what they respon...
DevOps is under attack because developers don’t want to mess with infrastructure. They will happily ...
"As we've gone out into the public cloud we've seen that over time we may have lost a few things - w...
In his session at 21st Cloud Expo, Michael Burley, a Senior Business Development Executive in IT Ser...
Sanjeev Sharma Joins June 5-7, 2018 @DevOpsSummit at @Cloud Expo New York Faculty. Sanjeev Sharma is...
We are given a desktop platform with Java 8 or Java 9 installed and seek to find a way to deploy hig...
"I focus on what we are calling CAST Highlight, which is our SaaS application portfolio analysis too...
"Cloud4U builds software services that help people build DevOps platforms for cloud-based software a...