7 Debugging

DEBUGGING

 

A debugger or debugging tool is a computer program that is used to test and debug other programs (the “target” program). Debugging is defined as a process of analyzing and removing the error. It is considered necessary in most of the newly developed software or hardware and in commercial products/ personal application programs. For complex products, debugging is done at all the levels of the testing. Debugging is considered to be a complex and time-consuming process since it attempts to remove errors at all the levels of testing. To perform debugging, debugger (debugging tool) is used to reproduce the conditions in which failure occurred, examine the program state, and locate the cause. With the help of debugger, programmers trace the program execution step by step (evaluating the value of variables) and halt the execution wherever required to reset the program variables. Note that some programming language packages include a debugger for checking the code for errors while it is being written.

 

Once errors are identified: it is necessary identify the precise location of the errors and to fix them. Each debugging approach has its own advantages and disadvantages: each is useful in appropriate circumstances.

 

THE DEBUGGING PROCESS

 

During debugging, errors are encountered that range from less damaging (like input of an incorrect function) to catastrophic (like system failure, which lead to economic or physical damage). Note that with the increase in number of errors, the amount of effort to find their causes also increases.

 

Once errors are identified in a software system, to debug the problem, a number of steps are followed, which are listed below.

    1.  Defect confirmation/identification: A problem is identified in a system and a defect report is created. A software engineer maintains and analyzes this error report and finds solutions to the following questions.

  1. Does a .defect exist in the system?
  2. Can the defect be reproduced?
  3. What is the expected/desired behavior of the system?
  4. What is the actual behavior?

   2.Defect analysis: If the defect is genuine, the next step is to understand the root cause of the problem.         Generally, engineers debug by starting a debugging tool (debugger) and they try to understand the root cause  of the problem by following a step-by-step execution of the program.

 

3.Defect resolution: Once the root cause of a problem is identified, the error can be resolved by making an appropriate change to the system by fixing the problem.

 

When the debugging process ends, the software is retested to ensure that no errors are left undetected. Moreover, it checks that no new errors are introduced in the software while making some changes to it during the debugging process

 

DEBUGGING STRATEGIES

 

As debugging is a difficult and time-consuming task, it is essential to develop a proper debugging strategy. This strategy helps in performing the process of debugging easily and efficiently. The commonly-used debugging strategies are debugging by brute force, induction strategy, deduction strategy, backtracking strategy, and debugging by testing.

 

Brute force method of debugging is the most commonly used but least efficient method. It is generally used when all other available methods fail. Here, debugging is done by taking memory (or storage) dumps. Actually, the program is loaded with the output statements that produce a large amount of information including the intermediate values. Analyzing this information will help to identify the errors cause. However, using a memory dump for finding errors requires analyzing huge amount of information or irrelevant data leading to waste of time and effort.

 

This strategy is a ‘disciplined thought process’ where errors can be debugged by moving outwards from the particulars to the whole. This strategy assumes that once the symptoms of the errors are identified, and the relationships between them are established, the errors can be easily detected by just looking at the symptoms and the relationships.

 

BRUTE – FORCE METHOD

 

This is the most common method of debugging are least efficient method, program is loaded with print statements, print the intermediate values, hope that some of printed values will help identify the error.

 

SYMBOLIC DEBUGGER

 

Brute force approach becomes more systematic with the use of a symbolic debugger, symbolic debuggers get their name for historical reasons, early debuggers let the programmer only to see values from a program dump to determine which variable it corresponds to.

 

SYMBOLIC DEBUGGER

 

Using a symbolic debugger the values of different variables can be easily checked and modified, single stepping to execute one instruction at a time, break points and watch points can be set to test the values of variables.

 

BACKTRACKING

 

Backtracking is a fairly common approach. Beginning at the statement where an error symptom has been observed such as source code is traced backwards until the error is discovered. Unfortunately, as the number of source lines to be traced back increases, the number of potential backward paths increases, becomes unmanageably large for complex programs.

 

CAUSE-ELIMINATION METHOD

 

Determine a list of causes which could possibly have contributed to the error symptom, tests are conducted to eliminate each. A related technique of identifying error by examining error symptoms: software fault tree analysis.

 

PROGRAM SLICING

 

This technique is similar to back tracking. However, the search space is reduced by defining slices. A slice is defined for a particular variable at a particular statement: set of source lines preceding this statement which can influence the value of the variable.

 

Example

 

int main(){

 

int i,s;

 

i=1; s=1;

 

while(i<=10){

 

s=s+i;

 

i++;}

 

printf(“%d”,s);

 

printf(“%d”,i);

 

}

 Here, unused variables must be eliminated.

 

DEBUGGING GUIDELINES

 

Debugging usually requires a thorough understanding of the program design. Debugging may sometimes require full redesign of the system. A common mistake novice programmers often make: not fixing the error but the error symptoms. Be aware of the possibility because an error correction may introduce new errors. After every round of error-fixing, regression testing must be carried out.

 RULES FOR PERFORMING DEBUGGING

  1. Debugging is the process of solving a problem. Hence, individuals involved in debugging should understand all the causes of an error before starting with debugging.
  1. No experimentation should be done while performing debugging. The experimental changes instead of removing errors often increase the problem by adding new errors in it.
  1. When there is an error in one segment of a program, there is a high possibility that some other errors also exist in the program. Hence, if an error is found in one segment of a program, rest of the program should be properly examined for errors.
  1. It should be ensured that the new code added in a program to fix errors is correct and is not introducing any new error in it. Thus, to verify the correctness of a new code and to ensure that no new errors are introduced, regression testing should be performed.

DEBUGGING TOOLS

 

Typically, debuggers also offer more sophisticated functions such as running a program step by step (single-stepping or program animation), stopping (breaking) (pausing the program to examine the current state) at some event or specified instruction by means of a breakpoint, and tracking the values of some variables. Some debuggers have the ability to modify the state of the program while it is running, rather than merely to observe it. It may also be possible to continue execution at a different location in the program to bypass a crash or logical error.

 

A “crash” happens when the program cannot normally continue because of a programming bug. For example, the program might have tried to use an instruction not available on the current version of the CPU or attempted to access unavailable or protected memory. When the program “crashes” or reaches a preset condition, the debugger typically shows the position in the original code if it is a source-level debugger or symbolic debugger, commonly now seen in integrated development environments. If it is a low-level debugger or a machine-language debugger it shows the line in the disassembly (unless it also has online access to the original source code and can display the appropriate section of code from the assembly or compilation).

 

DEBUGGING TOOLS

 

Typically, debuggers also offer more sophisticated functions such as running a program step by step (single-stepping or program animation), stopping (breaking) (pausing the program to examine the current state) at some event or specified instruction by means of a breakpoint, and tracking the values of some variables. Some debuggers have the ability to modify the state of the program while it is running, rather than merely to observe it. It may also be possible to continue execution at a different location in the program to bypass a crash or logical error.

 

A “crash” happens when the program cannot normally continue because of a programming bug. For example, the program might have tried to use an instruction not available on the current version of the CPU or attempted to access unavailable or protected memory. When the program “crashes” or reaches a preset condition, the debugger typically shows the position in the original code if it is a source-level debugger or symbolic debugger, commonly now seen in integrated development environments. If it is a low-level debugger or a machine-language debugger it shows the line in the disassembly (unless it also has online access to the original source code and can display the appropriate section of code from the assembly or compilation).

PROGRAM ANALYSIS TOOLS

 

An automated tool takes program source code as input produces reports regarding several important characteristics of the program, such as size, complexity, adequacy of commenting, adherence to programming standards, etc. Some program analysis tools produce reports regarding the adequacy of the test cases. There are essentially two categories of program analysis tools namely Static analysis tools and Dynamic analysis tools.

 

Static Analysis Tools

 

Static analysis tools assess properties of a program without executing it. Analyze the source code to provide analytical conclusions. Whether coding standards have been adhered to? Commenting is adequate. Programming errors such as Un-initialized variables mismatch between actual and formal parameters. Variables declared but never used, etc. Code walk through and inspection can also be considered as static analysis methods. However, the term static program analysis is generally used for automated analysis tools.

 

Dynamic Analysis Tools

 

Dynamic program analysis tools require the program to be executed, its behaviour recorded.

Produce reports such as adequacy of test cases.

 

DEBUGGING BY TESTING

 

This debugging method can be used in conjunction with debugging by induction and debugging by deduction methods. Additional test cases are designed that help in obtaining information to devise and prove a hypothesis in induction method and to eliminate the invalid causes and refine the hypothesis in deduction method. Note that the test cases used in debugging are different from the test cases used in testing process. Here, the test cases are specifically designed to explore the internal program state.

 

 

CONCLUSIONS

 

Debugging is performed after testing; this is useful for checking the code. Backtracking helps to find the source of error. Break points can be used to run the program step by step. This can be achieved by using program slicing also. Debugging using debuggers reduces the time than manual debugging. Therefore, all modern compilers are provided with a debugging facility along with the programming language to be used as a single package.