You are on page 1of 9

1

CEN 4020 Software Engineering Essay No. 1: Spring 2012 Active learning project: debugging methods Submission deadline: February 16, 2012

Full name: Lindsey Segal USFID: U68581935 E-mail: lsegal@mail.usf.edu

Abstract Debugging a program is an essential part of the software engineering process. Determining how to fix these errors quickly and efficiently is not only important for the users of these programs, but it also aids in improving the ability for a programmer to create in depth and correct code. Today, there are a variety of techniques that help novice and advanced developers, but there are still many areas related to debugging that could be improved on. In this report I will first begin by explaining the general principles of debugging, including what it is and why debugging is such an important area of interest. I will then describe the various methods available to fix programming bugs. Finally, I will show examples of debugging code and additional pieces of software that allow debugging to be less time intensive and more proficient. Key Terms Breakpoint Postmortem debugging On-line debugging Fault localization I. Introduction -Definition of debugging. Why this does not depict how important this area is. II. General Information According to Terence Parr, professor of computer science at the University of San Francisco, the debugging process can be divided into six steps. By following these guidelines, you can become a more efficient debugger by separating one big problem into smaller sections. Although this is still a challenging feat, there is peace of mind knowing that this is not one large task but instead smaller and less stressful components that can bring you to the final solution. This process includes: reproducibility, reduction, deduction, experimentation, experience, and tenacity [1].
i. Reproducibility CEN 4020 Software Engineering: Essay No. 1

The main goal here is to find the error and reproduce the effect for further evaluation. Sometimes the bug exists in only one line of code, which allows us to solve the problem easily. Other time there are multiple bugs existing on multiple lines of code, or the bug appears intermittently during execution. Either way, replicating these errors in a reliable manner is vital to perform the entire debugging process. One way to replicate these bugs is through fault localization through trace comparison which is described in the report by University of Singapore student Abhik Roychoudhury [2]. This method involves executing the program multiple times and then comparing the results against each other to determine where the error exists. The failed run is considered to be the executed program that produces some type of invalid or unexpected input. This is then compared with a successful run which is deemed correct if there is no unexpected behavior present. Once we determine the runs to compare, we use what Roychoudhury refers to as a difference metric, which computes the difference between these executions. The difference between the runs then determines what should be considered when determining where the bug is located. Below is an example of this method to reproduce and determine the location of the errors.

Figure 1. Fault Localization Methods. ii. Reduction

This goal of this step is to reduce the amount of data necessary to reproduce the bug. For example, if you have a large data file, you can split in half and use the first portion to debug your code. If you find that the error disappears after this split, then you know that the error is somewhere in the other half of the file. Following this step can lead to a quick find for an error, or at least reduce the amount of unneeded data to decipher. I personally have used this method to determine the cause of an error in a program. During my Data Structures course, we were required to complete a project that used a csv file as our input into the program. My partner and I sat there for hours trying to determine the cause of our error when we decided to split up the data file into smaller sections. After doing this, we realized that although the first half of the csv looked identical, there was one single line that was longer than the rest, causing our program to output incorrectly. If we

CEN 4020 Software Engineering: Essay No. 1

had decided to do this initially, we could have saved ourselves a lot of time and headaches trying to determine what we did wrong.
iii. Deduction & Experimentation

These two areas in the process are an accumulation of steps one and two. Deduction is the area where you take the components causing the bug and determine where and why this is happening. In the example of my error in the data structures program, we took the area where the error was occurring and located its corresponding code to correct this bug. Around this point is where experimentation would occur and also where novice programmers may implement the famous print statement technique. This easy debugging method is utilized by simply including print statements for some or all of the variables that may be associated with the error. Although this is not a recommended technique, it does allow those with little programming or debugging experience to isolate the problem. Experimentation is vital in the determination of bugs because this is where you modify and change your code until you see a noticeable improvement in the output of your program. Without the experimental step, I believe little would be understood in the area of debugging and even less for those just entering this ever expanding field.
iv. Experience

This next area may seem obvious, but you can never stress enough to those starting off as programmers the power of experience. The more you write code, the more you can understand the ins and outs of computer programming. The same goes for the area of debugging, which many believe to be equally important, if not more important than the program implementation itself. Becoming an experienced program debugger means that you have made mistakes, but you have also learned from them. This also prevents you from making the same mistakes in the future and to catch mistakes before they cause major problems in your code. Also, learning from those that are more experience than you can help improve your programming and debugging skills. Although experience comes with time, you can always learn from others and find new ways of doing things that may help your coding and debugging abilities in the future.
v. Tenacity

Although this may not be a definable step in the debugging process, it is important nevertheless. Giving up will not help you improve your understanding of the programming and error checking processes. Being a programmer means you must push forth even if you feel discouraged. Being tenacious not only aids in your debugging abilities, but it helps you understand that although this may be a long and tedious process, there is a light at the end of the tunnel that only you can get to. You are the main component in the debugging process and you must be the one to keep going no matter what.

III. Debugging Categories


CEN 4020 Software Engineering: Essay No. 1

In addition to the process of debugging, there are also three different categories within the realm of debugging. These include syntax, runtime, and semantic errors which are discussed below.
i. Syntax

Syntactic errors are errors that are specific to the language you are writing your program in. If your syntax is off, the compiler will generate an error or warning telling you something is wrong. An example of a syntax error would be forgetting to capitalize a key word. For example, in Java if you capitalize the word class or int, you will receive an error similar to class or interface declaration expected, implying that there is something wrong with your declarations. Some other examples of syntax errors include missing arguments in a function call, missing semi-colons or missing curly brackets to surround your class or functions. Without first fixing these types of errors, you will never be able to successfully run your code.
ii. Runtime

Runtime errors are not visible until you execute your program. These errors are also known as exceptions because they refer to some type of exceptional occurrence that is causing bad or unexpected out. Runtime errors can also be some of the most difficult to correct. They can occur for multiple reasons, some including memory allocation, infinite loops, and pointer references. These are all possible causes because they are not visible at first to a programmer but once the code has been compiled and run, you see these types of errors pop up.
iii. Semantic

Semantic errors can also be referred to as logical errors. These peicies of code may look syntactically correct, but once compiled the output produces invalid values. This is because the logic behind the code is invalid. One example of a semantic error is using the = instead of the == operator when doing a calculation. The = operator assigns a value, while the == is a logical operator to check if two things are equal. They may look similar, but they are in fact very different. These errors are also very common for beginning programmers mainly because they havent had the proper experience related to programming logic. I know from personal experience that this is the area where I have always seen the majority of my errors. Some may be easy to fix, while others can be a quite difficult to decipher. Using specific techniques is how many novice and advanced programmers can accomplish this area of debugging. IV. Debugging & Unit Testing The techniques used to debug programs are a part of a field that is still expanding. Computer scientists are still finding improvements in the current methods implemented and developing new ways to debug code in a more efficient and less manual manners. The section begins with the types of debugging preferences used by novice programmers, and progresses into the more advanced systems used to rid code of these unattractive errors.
CEN 4020 Software Engineering: Essay No. 1

i.

The Print Statement

This technique is one that has been used for many years and by many developers in the programming world. Although this can be an easy way to catch unexpected output or to check the values of your variables, it is not as efficient as one would desire. The way this method works is by inserting print statements into your source code so that you can see an output of values for every variable you believe to be the culprit behind your errors. This method also allows you to track the flow of your program, which can be very important if there are semantic errors that are not directly visible in your code. Since I began my career in the field of Computer Science, I have always chosen this technique as my primary choice when I found output that I did not intend to see. I mainly chose this method for its simplicity, as many programmers starting out do, but it certainly is not efficient. Too many print statements can bog down your code, making it either unreadable or overwhelming. If you choose to use print statements you may output more code than you need to determine the cause of your error. One example of this comes from my former programming partner, who created a file that inserted print statements for every variable and line in a program. Although this made this method less cumbersome, in the end you were still seeing so many lines of output that in some cases it tended to confuse you more. Although many people believe this technique is outdated and inefficient, it is still used by programmers of all levels of expertise. There are now new ways to debug code that are more useful and effective at determining the location and cause of an error without the manual insertion of print statements.
ii. Test Case Scenarios

This may not be a defined type of debugging but testing program functionality is definitely a valuable method to determine if your code is running correctly. For the novice, this would include inputting a letter when you should be entering a number, or attempting to max out an array. Debugging code in this manner can help programmers find errors that they may not have anticipated to occur. Additionally, this type of debugging technique can be very helpful when launching new software to multiple users. Before the launch, companies utilize test cases by having people test their programs before they are sent out to the customers. Without this step it is possible that a piece of software could be sent out into the world with bugs which could be extremely problematic. This is further discussed in the section Postmortem Debugging.
iii. The Debugger

According to student P. Adragna of the University of London, a debugger allows working through the code line-by-line to find out what is going wrong, where and why. It allows working interactively, controlling the execution of the program, stopping it at various times, inspecting variables, changing code flow whilst running. [4] I think this definition perfectly sums up the concept of using the debugger. Once you develop a sense of how they work, debuggers can become your best friend when a program goes awry.
CEN 4020 Software Engineering: Essay No. 1

One of the main features of using the debugger is the ability to set breakpoints in your code. Using breakpoints allows you to control the flow of execution, allowing you to skip over working areas and focus on the areas that are actually causing the problems. Breakpoints can be placed at specific line numbers, the start of a function or loop, and at defined addresses [4]. The debugger allows you to step in, step out, or step over specific areas in your program. This can be extremely helpful to see what is happening and why. For example, you can set a breakpoint at the beginning of a function and then step into this function to see what values are being stored in your variables. This allows you to see what your function is doing a line at a time, which can be very useful. If you were to step over a function, you would not be executing the code but taking that block and basically ignoring it. This can be beneficial if you are certain there is nothing wrong with this particular function and you just want to execute the code at the next breakpoint. Using breakpoints also helps you to see what the compiler is seeing. For example, in Visual Studio, there is a window that will tell you what a variable is when you are stepping into a function. I have used this many times and find this to be very helpful when trying to figure out what is going wrong. An example of the Visual Studio debugger is shown below. When comparing the debugger to the print statement method, you can see that these techniques greatly. The debuggers interactive qualities allow you to choose what you want to see and where you want to start the execution of your code. Using print statements forces you to manual insert temporary lines into your code in order to determine where the bug is located. Although the print statement method is a preferred choice for a wide range of programmers, the debugger still has many positive qualities that I think people should consider when debugging programs.
iv. Postmortem Debugging

Postmortem debugging is extremely useful for companies employing software on multiple systems or to a large group of customers. According to David Pacheco, Stanley Gill described the post mortem technique by saying the running program was modified to record important system state as it ran so that the programmer could later understand what happened and why the software failed. [5] Since Gills description in 1951, this postmortem technology has been utilized in a variety of systems, including operating systems and native execution environments. [5] This type of debugging has been because although there may be a large amount of testing and debugging done prior to sending out a new piece of software, but there may still be intermittent bugs that were not seen prior to the launch. This is where the postmortem debugging technique comes in. When a program crashes, the goal is to have a resource that allows you to save all program state information. After the state information is stored, the program can be restarted to avoid having too many users seeing these bugs and also to allow service to be up and running quickly. Using this method can be very beneficial because it allows programmers to fix bugs that are intermittent or root-caused in any stage of program development.
CEN 4020 Software Engineering: Essay No. 1

In order for postmortem debugging to be successful, the following areas must be satisfied. First, the software should not include any need for modifications that may impact performance of the software. Also, the postmortem facility that is utilized should be permanently on without any need for additional add-ons to support the debugging process. Additionally, the save state information must include a stack trace so that program information can be observed in detail. This state information should provide enough information for developers to locate the root cause of the problem after seeing an error one time. Finally, the state information, or the dump must be able to be transferred from one system to another for analysis purposes. Allowing this to be used on multiple systems makes it much easier for computer scientists to locate the cause using an environment they are already familiar with to quickly find the problem [5]. Postmortem debugging can be extremely useful if you are required to debug complex software, enterprise systems, or operating systems, but there are still some drawbacks associated with this technique. One of the main disadvantages related to this method is the fact that the state information must be saved ahead of time, which results in important information being ignored. Some of this state information can include function arguments on the call stack and also contexts related to future events [5]. Unfortunately this information cannot be reachable from a global scope, which is why this is a primary drawback. Also, there is the possibility that the amount of memory needed could be larger than the entire heap, causing this technique to be unreliable in the event that we utilize more memory for serialization and code dumps [5]. Regardless of these pitfalls, the postmortem method has still been found to be effective because of the requirements described in the previously.
v. Unit Testing Techniques

V. Examples & Code -visual studio debugger -example print out Reverse engineering a technique of taking something and figuring out how it was made. Applys to hacking and engineering. Take a bridge and reverse engineer it to see how they made the structure. Use in programs to find flaws. Command line debugger for hacking purposes VI. Conclusion
BACKGROUND Software engineering contains lots of high-level techniques for the entire design process, covering the full range from requirement analysis to post-delivery evolution. The topic that had little attention

CEN 4020 Software Engineering: Essay No. 1

is how to debug the code, i.e. what types of techniques and/or tools are available to get rid of those unwanted computer pests. OBJECTIVES The main objective of this active learning project is to systematically study the art and the daily practice of code debugging. You will study various programming practices to see how the skill of code debugging can be acquired, and how it can be further developed to assist the software engineer to mature into a high-profile code developer. PROJECT DESCRIPTION This project consists of the following simple elements: Understand the concept of program design as presented in the book, in class, and perhaps in other classes you may have taken. Search for topics like debugging, code testing, watchdogs, fault-free coding, etc. Do a search on code debugging techniques and dig out all useful and understandable information. Find methods and available systems for debugging. Find publicly available code and/or demo programs related to debugging. Once the research is done, digest all the information you gathered and write-up your experience with your independent research as described in the next section. DELIVERABLES Using this file as a template, write an essay of no more than 5,000 words that contains, as a minimum, the following components: A short abstract of no more than 200 words. A list of keywords of no more than 5. An introduction section where you describe the problem domain and give a short description of prior approaches as far as you know. A section on general debugging methods. A section on unit testing techniques, which describes the result of your independent research. Proper illustrations throughout the text. A section on examples and demos, if any. A section on experiments, if available or if you have done one or more yourself. FORMAT Use this MS Word file as the template and enter your text directly after the E-mail heading. The essay should be less than 5,000 words or less than 10 pages, not including illustrations and references. Please name the file as follows: First name_Last name_Essay No.doc, e.g. John_Doe_1.doc When submitting the file, the subject line should contain the course prefix as well as the file name above. Example: CEN 4020 Software Engineering: Essay No. 1

CEN_4020_John_Doe_1.doc SUBMISSION Your essay should be submitted electronically via e-mail attachment. Please send the file to lpiegl@gmail.com no later than February 16, 2012. (Please do not write below this line) Grade: Comments:

CEN 4020 Software Engineering: Essay No. 1

You might also like