Softwares have been there for more than a hundred and fifty years (the first software was written in 1842.), but have become a significant part of our lives in the past few decades. With increasing dependence on software, it becomes important that they do not crash or even behave non-deterministically in certain cases. Not just these crashes irritate the end user but also are known to cause losses to the tune of millions of dollars. For example, Therac-25, a radiation therapy machine was involved in the deaths of over three patients and injured over four patients because of a simple concurrency bug that caused it to deliver lethal doses of radiations to the patients. There can be a number of reasons for such failures like syntactical errors, null pointer dereferencing, data races, communication errors and more. These are referred as software bugs. Developers invest substantial time developing and testing these applications, yet often some bugs remain that are triggered when a set of predicates are satisfied.
Considering the criticality of a software, it is desirable to know if it has bugs so that they can be fixed before causing any monetary or physical loss. The process of detecting bugs and locating them is known as fault localization. Depending on the nature of the bug, different fault localization techniques are employed. These can be broadly classified as static, dynamic and hybrid techniques (No matter what testing techniques you apply, you can only determine the presence of a bug but can never guarantee the absence of a bug). In static analysis, the code is analyzed without executing it. Syntax error detection by IDEs is an example static analysis. Accordingly, in dynamic analysis, the program is executed to detect the bugs. Hybrid techniques are the combination of these two.
All these techniques come with their own bags of pros and cons which make them suitable for a particular scenario. For example, static analysis will traverse the program code line by line and capture some features. These features may not be as informative as dynamic or hybrid analysis would have produced but it is a faster technique. These techniques can be used to detect a presence of a bug but not the absence of bugs.
A particular analysis may capture a particular information about the code in certain cases and fail in others. For example in case of unreachable code detection, static analysis may detect a case like:
int foo()
{
int a=10;
return a;
a++; //unreachable code : detectable code by static analysis
}
But will fail in cases like:
int foo()
{
int a=10;
if(a==a)
return a;
a++; //unreachable code : not detectable code by static analysis
}
All these techniques come with their own bags of pros and cons which make them suitable for a particular scenario. For example, static analysis will traverse the program code line by line and capture some features. These features may not be as informative as dynamic or hybrid analysis would have produced but it is a faster technique. These techniques can be used to detect a presence of a bug but not the absence of bugs.
A particular analysis may capture a particular information about the code in certain cases and fail in others. For example in case of unreachable code detection, static analysis may detect a case like:
int foo()
{
int a=10;
return a;
a++; //unreachable code : detectable code by static analysis
}
But will fail in cases like:
int foo()
{
int a=10;
if(a==a)
return a;
a++; //unreachable code : not detectable code by static analysis
}