TL;DR: It is found that even well tested code written by experts contains a surprising number of obvious bugs and that simple automatic techniques can be effective at countering the impact of both ordinary mistakes and misunderstood language features.
Abstract: Many techniques have been developed over the years to automatically find bugs in software. Often, these techniques rely on formal methods and sophisticated program analysis. While these techniques are valuable, they can be difficult to apply, and they aren't always effective in finding real bugs.Bug patterns are code idioms that are often errors. We have implemented automatic detectors for a variety of bug patterns found in Java programs. In this extended abstract1, we describe how we have used bug pattern detectors to find serious bugs in several widely used Java applications and libraries. We have found that the effort required to implement a bug pattern detector tends to be low, and that even extremely simple detectors find bugs in real applications.From our experience applying bug pattern detectors to real programs, we have drawn several interesting conclusions. First, we have found that even well tested code written by experts contains a surprising number of obvious bugs. Second, Java (and similar languages) have many language features and APIs which are prone to misuse. Finally, that simple automatic techniques can be effective at countering the impact of both ordinary mistakes and misunderstood language features.
TL;DR: The Whyline is a prototype Interrogative Debugging interface for the Alice programming environment that visualizes answers in terms of runtime events directly relevant to a programmer's question.
Abstract: Debugging is still among the most common and costly of programming activities. One reason is that current debugging tools do not directly support the inquisitive nature of the activity. Interrogative Debugging is a new debugging paradigm in which programmers can ask why did and even why didn't questions directly about their program's runtime failures. The Whyline is a prototype Interrogative Debugging interface for the Alice programming environment that visualizes answers in terms of runtime events directly relevant to a programmer's question. Comparisons of identical debugging scenarios from user tests with and without the Whyline showed that the Whyline reduced debugging time by nearly a factor of 8, and helped programmers complete 40% more tasks.
TL;DR: It is found that even well tested code written by experts contains a surprising number of obvious bugs, and that simple automatic techniques can be effective at countering the impact of both ordinary mistakes and misunderstood language features.
Abstract: Many techniques have been developed over the years to automatically find bugs in software. Often, these techniques rely on formal methods and sophisticated program analysis. While these techniques are valuable, they can be difficult to apply, and they aren't always effective in finding real bugs.Bug patterns are code idioms that are often errors. We have implemented automatic detectors for a variety of bug patterns found in Java programs. In this paper, we describe how we have used bug pattern detectors to find serious bugs in several widely used Java applications and libraries. We have found that the effort required to implement a bug pattern detector tends to be low, and that even extremely simple detectors find bugs in real applications.From our experience applying bug pattern detectors to real programs, we have drawn several interesting conclusions. First, we have found that even well tested code written by experts contains a surprising number of obvious bugs. Second, Java (and similar languages) have many language features and APIs which are prone to misuse. Finally, that simple automatic techniques can be effective at countering the impact of both ordinary mistakes and misunderstood language features.
TL;DR: By changing the way assignments are assessed--where students are responsible for demonstrating correctness through testing, and then assessed on how well they achieve this goal--it is possible to reinforce desired skills.
Abstract: Introductory computer science students rely on a trial and error approach to fixing errors and debugging for too long. Moving to a reflection in action strategy can help students become more successful. Traditional programming assignments are usually assessed in a way that ignores the skills needed for reflection in action, but software testing promotes the hypothesis-forming and experimental validation that are central to this mode of learning. By changing the way assignments are assessed--where students are responsible for demonstrating correctness through testing, and then assessed on how well they achieve this goal--it is possible to reinforce desired skills. Automated feedback can also play a valuable role in encouraging students while also showing them where they can improve.
TL;DR: An adaptive profiling scheme is described that addresses poor coverage of infrequently executed code, by sampling executions of code segments at a rate inversely proportional to their execution frequency by implementing SWAT, a novel memory leak detection tool.
Abstract: Sampling has been successfully used to identify performance optimization opportunities. We would like to apply similar techniques to check program correctness. Unfortunately, sampling provides poor coverage of infrequently executed code, where bugs often lurk. We describe an adaptive profiling scheme that addresses this by sampling executions of code segments at a rate inversely proportional to their execution frequency. To validate our ideas, we have implemented SWAT, a novel memory leak detection tool. SWAT traces program allocations/ frees to construct a heap model and uses our adaptive profiling infrastructure to monitor loads/stores to these objects with low overhead. SWAT reports 'stale' objects that have not been accessed for a 'long' time as leaks. This allows it to find all leaks that manifest during the current program execution. Since SWAT has low runtime overhead (‹5%), and low space overhead (‹10% in most cases and often less than 5%), it can be used to track leaks in production code that take days to manifest. In addition to identifying the allocations that leak memory, SWAT exposes where the program last accessed the leaked data, which facilitates debugging and fixing the leak. SWAT has been used by several product groups at Microsoft for the past 18 months and has proved effective at detecting leaks with a low false positive rate (‹10%).
TL;DR: The Chronus tool is presented, which automates the task of searching for a failure-inducing state change and can diagnose a range of common configuration errors for both client-side and server-side applications, and that the performance overhead of the tool is not prohibitive.
Abstract: This work addresses the problem of diagnosing configuration errors that cause a system to function incorrectly. For example, a change to the local firewall policy could cause a network-based application to malfunction. Our approach is based on searching across time for the instant the system transitioned into a failed state. Based on this information, a troubleshooter or administrator can deduce the cause of failure by comparing system state before and after the failure.
We present the Chronus tool, which automates the task of searching for a failure-inducing state change. Chronus takes as input a user-provided software probe, which differentiates between working and nonworking states. Chronus performs "time travel" by booting a virtual machine off the system's disk state as it existed at some point in the past. By using binary search, Chronus can find the fault point with effort that grows logarithmically with log size. We demonstrate that Chronus can diagnose a range of common configuration errors for both client-side and server-side applications, and that the performance overhead of the tool is not prohibitive.
TL;DR: In this article, a system for debugging targets using various techniques, some of which are particularly useful in a multithread environment, is presented, such as implementing breakpoints using out-of-line instruction emulation so that an instruction replaced with a breakpoint instruction does not need to be returned to its original location for single-step execution.
Abstract: A system for debugging targets using various techniques, some of which are particularly useful in a multithread environment. These techniques include implementing breakpoints using out-of-line instruction emulation so that an instruction replaced with a breakpoint instruction does not need to be returned to its original location for single-step execution, executing a debugger nub for each target as part of the target task but using a nub task thread for the nub execution that is separate from the target task threads, providing immunity from breakpoints for specified threads such as the nub thread via specialized breakpoint handlers used by those threads, and virtualizing the debugger nub such that a shared root nub provides a uniform interface between the debugger and the target while specialized nubs provide differing functionality based on the type of target being debugged.
TL;DR: In this article, a system and method for facilitating and simplifying testing and debugging of computer programs is described, where a computer program is broken down to smaller components, such as, classes, functions, or objects, and then those smaller components are tested individually.
Abstract: A system and method for facilitating and simplifying testing and debugging of computer programs. is described A computer program is broken down to smaller components, such as, classes, functions, or objects, and then those smaller components are tested individually. Accordingly, specific aspects of the computer program can be effectively tested. The user can automatically perform a range of tests on a class or method when the class or method is compiled without integrating the class or method into a larger project.
TL;DR: A novel statistics-based, on-the-fly bug detection method called PC-based invariant detection, which can detect bugs that do not violate any programming rules and that are likely to be missed by many existing tools, and a novel architectural extension called the Check Look-aside Buffer (CLB).
Abstract: This paper makes two contributions to architectural support for software debugging. First, it proposes a novel statistics-based, on-the-fly bug detection method called PC-based invariant detection. The idea is based on the observation that, in most programs, a given memory location is typically accessed by only a few instructions. Therefore, by capturing the invariant of the set of PCs that normally access a given variable, we can detect accesses by outlier instructions, which are often caused by memory corruption, buffer overflow, stack smashing or other memory-related bugs. Since this method is statistics-based, it can detect bugs that do not violate any programming rules and that, therefore, are likely to be missed by many existing tools. The second contribution is a novel architectural extension called the Check Look-aside Buffer (CLB). The CLB uses a Bloom filter to reduce monitoring overheads in the recently-proposed iWatcher architectural framework for software debugging. The CLB significantly reduces the overhead of PC-based invariant debugging. We demonstrate a PC-based invariant detection tool called AccMon that leverages architectural, run-time system and compiler support. Our experimental results with seven buggy applications and a total of ten bugs, show that AccMon can detect all ten bugs with few false alarms (0 for five applications and 2-8 for two applications) and with low overhead (0.24-2.88 times). Several existing tools evaluated, including Purify, CCured and value-based invariant detection tools, fail to detect some of the bugs. In addition, Purify's overhead is one order of magnitude higher than AccMon's. Finally, we show that the CLB is very effective at reducing overhead.
TL;DR: The Intelligent Watcher (iWatcher), novel architectural support to monitor dynamic execution with minimal overhead, automatically, and flexibly, and Thread-Level Speculation (TLS), which is effective at reducing overheads for programs with substantial monitoring.
Abstract: Recent impressive performance improvements in computer architecturehave not led to significant gains in ease of debugging.Software debugging often relies on inserting run-time softwarechecks. In many cases, however, it is hard to find the root causeof a bug. Moreover, program execution typically slows down significantly,often by 10-100 times.To address this problem, this paper introduces the IntelligentWatcher (iWatcher), novel architectural support to monitor dynamicexecution with minimal overhead, automatically, and flexibly.iWatcher associates program-specified monitoring functionswith memory locations. When any such location is accessed, themonitoring function is automatically triggered with low overhead.To further reduce overhead and support rollback, iWatcher canleverage Thread-Level Speculation (TLS). To test iWatcher, we useapplications with various bugs. Our results show that iWatcher detectsmany more software bugs than Valgrind, a well-known open-sourcebug detector. Moreover, iWatcher only induces a 4-80%execution overhead, which is orders of magnitude less than Valgrind.Even with 20% of the dynamic loads monitored in a program,iWatcher adds only 66-174% overhead. Finally, TLS is effective atreducing overheads for programs with substantial monitoring.
TL;DR: Microsoft Research has developed two generations of correctness tools, some of which Microsoft developers already use to find and correct bugs and can improve software development by systematically detecting programming errors.
Abstract: What tools do we use to develop and debug software? Most of us rely on a full-screen editor to write code, a compiler to translate it, a source-level debugger to correct it, and a source-code control system to archive and share it. These tools originated in the 1970s, when the change from batch to interactive programming stimulated the development of innovative languages, tools, environments, and other utilities we take for granted. Microsoft Research has developed two generations of tools, some of which Microsoft developers already use to find and correct bugs. These correctness tools can improve software development by systematically detecting programming errors.
TL;DR: Results from data compression are used to compactly represent bytecode traces of sequential Java programs and it is shown how dynamic slicing algorithms can directly traverse the authors' compact traces without resorting to costly decompression.
Abstract: Dynamic slicing is a well-known program debugging technique. Given a program P and input I, it finds all program statements which directly/indirectly affect the values of some variables' occurrences when P is executed with I. Dynamic slicing algorithms often proceed by traversing the execution trace of P produced by input I (or a dependence graph which captures control/data flow in the execution trace). Consequently, it is important to develop space efficient representations of the execution trace. In this paper, we use results from data compression to compactly represent bytecode traces of sequential Java programs. The major space savings come from the optimized representation of data (instruction) addresses used by memory reference (branch) bytecodes as operands. We give detailed experimental results on the space efficiency and time overheads for our compact trace representation. We then show how dynamic slicing algorithms can directly traverse our compact traces without resorting to costly decompression. We also develop an extension of dynamic slicing which allows us to explain omission errors (i.e. why some events did not happen during program execution).
TL;DR: In this article, a controller, referred to as the "BMonitor", is situated on a computer, which includes a plurality of filters that identify where data can be sent to and/or received from, such as another node in a co-location facility or a client computer coupled to the computer via the Internet.
Abstract: A controller, referred to as the “BMonitor”, is situated on a computer. The BMonitor includes a plurality of filters that identify where data can be sent to and/or received from, such as another node in a co-location facility or a client computer coupled to the computer via the Internet. The BMonitor further receives and implements requests from external sources regarding the management of software components executing on the computer, allowing such external sources to initiate, terminate, debug, etc. software components on the computer. Additionally, the BMonitor operates as a trusted third party mediating interaction among multiple external sources managing the computer.
TL;DR: In this paper, a human assisted method of debugging training data used to train a machine learning classifier is provided, which includes obtaining a classifier training data set and debugging it using an integrated debugging tool configured to implement a debugging loop.
Abstract: A human assisted method of debugging training data used to train a machine learning classifier is provided. The method includes obtaining a classifier training data set. The training data set is then debugged using an integrated debugging tool configured to implement a debugging loop to obtain a debugged data set. The debugging tool can be configured to perform an estimation and simplification step to reduce data noise in the training data set prior to further analysis. The debugging tool also runs a panel of prediction-centric diagnostic metrics on the training data set, and provides the user prediction based listings of the results of the panel of prediction-centric diagnostic metrics.
TL;DR: A new approach to dynamic information flow analysis is presented that can be used to detect and debug insecure flows in programs and incorporates a static preprocessing phase that permits detection of most implicit flows at runtime, in addition to explicit ones.
Abstract: A new approach to dynamic information flow analysis is presented that can be used to detect and debug insecure flows in programs. It can be applied offline to validate and debug a program against an information flow policy, or, when fast response is not critical, it can be applied online to prevent illegal flows in deployed programs. Since dynamic analysis alone is inherently unable to detect implicit information flows, our approach incorporates a static preprocessing phase that permits detection of most implicit flows at runtime, in addition to explicit ones. To support interactive debugging of insecure flows, it also incorporates a new forward computing algorithm for dynamic slicing, which is more precise than previous forward computing algorithms and is not restricted to programs with structured control flow. A prototype tool implementing the proposed approach has been developed for Java byte code programs. Case studies in which this tool was applied to several subject programs are described.
TL;DR: An empirical comparison of two interruption styles that have been used to alert end-user programmers to debugging information shows that negotiated- style interruptions were superior to immediate-style interruptions in several issues of importance to end- user debugging.
Abstract: Although researchers have begun to explicitly support end-user programmers' debugging by providing information to help them find bugs, there is little research addressing the proper mechanism to alert the user to this information. The choice of alerting mechanism can be important, because as previous research has shown, different interruption styles have different potential advantages and disadvantages. To explore impacts of interruptions in the end-user debugging domain, this paper describes an empirical comparison of two interruption styles that have been used to alert end-user programmers to debugging information. Our results show that negotiated-style interruptions were superior to immediate-style interruptions in several issues of importance to end-user debugging, and further suggest that a reason for this superiority may be that immediate-style interruptions encourage different debugging strategies.
TL;DR: A model of debugging abilities and habits based on students' comments in their debugging logs, development logs, reflective memos, and evaluation surveys is developed and could be used to diagnose students' current debugging skills and take actions to enhance their skills.
Abstract: We conducted a study to demonstrate that formal training in debugging helps students develop skills in diagnosing and removing defects from computer programs. To accomplish this goal in an assembly language course, we designed multiple activities to enhance students' debugging skills. These activities included debugging exercises, debugging logs, development logs and reflective memos, and collaborative assignments. In a previous paper, we reported positive qualitative results. Students agreed that formal debugging training enhanced their debugging skills. In this paper, we present positive quantitative results that support our previous qualitative results. Students who completed the optional debugging exercises spent significantly less time on debugging their programs than those who did not. Furthermore, we develop a model of debugging abilities and habits based on students' comments in their debugging logs, development logs, reflective memos, and evaluation surveys. Students and educators could use the model to diagnose students' current debugging skills and take actions to enhance their skills.
TL;DR: This paper describes a new hardware/software co-verification method for System-On-a-Chip, based on the integration of a C/C++ simulator and an inexpensive FPGA emulator, which enables easy debugging, rich portability, and high verification speed, at a low cost.
Abstract: This paper describes a new hardware/software co-verification method for System-On-a-Chip, based on the integration of a C/C++ simulator and an inexpensive FPGA emulator. Communication between the simulator and emulator occurs via a flexible interface based on shared communication registers. This method enables easy debugging, rich portability, and high verification speed, at a low cost. We describe the application of this environment to the verification of three different complex commercial SoCs, supporting concurrent hardware and embedded software development. In these projects, our verification methodology was used to perform complete system verification at 0.2-1.1 MHz, while supporting full graphical interface functions such as "waveform" or "signal dump" viewers, and debugging functions such as "step" or "break".
TL;DR: In this article, an incremental recompile of the compiled design compiles a routing from each internal signal to an output pin via the added registers, and the user views the internal signals at the output pins chosen.
Abstract: While debugging, a user chooses an incremental recompile. Internal signals of interest and output pins are selected, and a number of additional registers are chosen to insert in the path of each internal signal. A clock is selected for the registers. An incremental recompile of the compiled design compiles a routing from each internal signal to an output pin via the added registers. The database building and logic synthesis stages are skipped. The post-fitting logical netlist and routing netlist are retrieved. The new registers are created and the internal signal is connected to the output pin atom in the logical netlist. The fitter places and routes the connections to create a new routing netlist and then the new routing netlist is output into a programming output file (POF) in a form suitable for programming the PLD. The original routing netlist is undisturbed. The user views the internal signals at the output pins chosen. The user may iterate through this process many times in order to debug the PLD. The debugging assignments may be deleted.
TL;DR: An extensive suite of experiments with large sequential circuits confirm the robustness and efficiency of the proposed logic debugging methodology and suggest that Boolean satisfiability provides an effective platform for sequential logic debugging.
Abstract: Logic debugging of today's complex sequential circuits is an important problem. In this paper, a logic debugging methodology for multiple errors in sequential circuits with no state equivalence is developed. The proposed approach reduces the problem of debugging to an instance of Boolean satisfiability. This formulation takes advantage of modern Boolean satisfiability solvers that handle large circuits in a computationally efficient manner. An extensive suite of experiments with large sequential circuits confirm the robustness and efficiency of the proposed approach. The results further suggest that Boolean satisfiability provides an effective platform for sequential logic debugging.
TL;DR: This research presents a novel approaches to physical system simulation called "Smart Cassandra", which automates the very labor-intensive and therefore time-heavy and expensive process of designing and simulating physical systems.
Abstract: Mathematical modeling and simulation of complex physical systems is emerging as a key technology in engineering. Modern approaches to physical system simulation allow users to specify simulation mo ...
TL;DR: There's a simple technique that dramatically reduces the number of bugs in the authors' software, which will make most defects much easier to find and build their software to "fail fast".
Abstract: The most annoying aspect of software development is debugging. We don't mind the kinds of bugs that yield to a few minutes inspection. The bugs we hate are the ones that show up only after hours of successful operation, under unusual circumstances, or whose stack traces lead to dead ends. Fortunately, there's a simple technique that dramatically reduces the number of these bugs in our software. It won't reduce the overall number of bugs, at least not at first, but it'll make most defects much easier to find. The technique is to build our software to "fail fast".
TL;DR: In this article, the authors focus on programming technique rather than the requirements of a specific programming language or environment and apply good design techniques to construction, using data effectively, using common and advanced control structures, secrets of self-documenting code, testing and debugging techniques, improving performance with code tuning, managing construction activities, and relating personal character to the development of superior software.
Abstract: "Code complete" is the phrase used by programmers to announce the completion of a software program. Drawing its examples from a variety of computer languages, this book focuses on programming technique rather than the requirements of a specific programming language or environment. Steve McConnell developed True Type and Windows for the Microsoft Corporation. Topics include: front-end planning, applying good design techniques to construction, using data effectively, using common and advanced control structures, secrets of self-documenting code, testing and debugging techniques, improving performance with code tuning, managing construction activities, and relating personal character to the development of superior software.
TL;DR: JaRec correctly replays multi‐threaded, data‐race free Java applications, by recording the order of synchronization operations, and by executing them in the same order during replay.
Abstract: This paper describes JaRec, a portable record/replay system for Java. It correctly replays multi-threaded, data-race free Java applications, by recording the order of synchronization operations, and by executing them in the same order during replay. The record/replay infrastructure is developed in Java, and does not require a modification of the Java Virtual Machine (JVM) if it provides the JVM Profiler Interface (JVMPI). If the JVM does not support JVMPI, which is used for intercepting the loaded classes, only a minor modification to the JVM is required in order to run the system. On systems with limited memory resources, JaRec can be executed in a distributed fashion. This also makes it suitable to aid debugging of multi-threaded applications on embedded systems.
TL;DR: In this article, the authors propose a method for debugging OS kernel and applications software that does not require use of a hardware probe; can debug both user-mode programs and a significant body of the OS kernel code; allows the OS to continue servicing exceptions while debugging; leverages OS built-in device drivers for communicating devices to communicate with the host debugger; and can debug a production version of OS kernel.
Abstract: A method and apparatus for debugging of OS kernel and applications software that does not require use of a hardware probe; can debug both user-mode programs and a significant body of the OS kernel code; allows the OS to continue servicing exceptions while debugging; leverages OS built-in device drivers for communicating devices to communicate with the host debugger; and can debug a production version of the OS kernel. When debugging is required, the running OS kernel dynamically loads a software-based debug agent on demand whereby such debug agent dynamically modifies the running production OS kernel code and data to intercept debugging traps and provide run-control. To provide debugging of loadable module, the debug agent implement techniques to intercept the OS module loading system call; set breakpoints in the loaded module initialization function; calculate the start address of the debugged module in memory; and asynchronously put the system under debug. By structuring command loop to execute in non-exception mode, and devising a process to transfer execution from the debug agent exception handler to the debug agent command loop and back, the debug agent can communicate with the host debugger using interrupt-driven input/output devices as well as allowing the system to service interrupts while under debug.
TL;DR: In a case study, all six levels of Bloom's taxonomy of cognitive learning, from "knowledge through "comprehension", " application", "analysis", "synthesis", and "evaluation", are found, indicating that program debugging is a difficult cognitive task.
Abstract: Program debugging is a critical and complex activity in software engineering. Accurate and fast debugging leads to high quality software and a short time-to-market. Debugging involves a very demanding cognitive process. In a case study, we found all six levels of Bloom's taxonomy of cognitive learning, from "knowledge" through "comprehension", "application", "analysis", "synthesis", and "evaluation". The involvement of the higher levels of Bloom's taxonomy, such as synthesis and evaluation, indicates that program debugging is a difficult cognitive task. This fact may explain the difference between novices and experts in debugging effectiveness.
TL;DR: In this article, the authors present a tool which includes spatial information for configuring and managing a process control system which conforms to a standard protocol, such a tool advantageously allows the efficient design and use of a process controller system while ensuring that the physical characteristics of the system conform to the standard.
Abstract: The present invention is directed to a tool which includes spatial information for configuring and managing a process control system which conforms to a standard protocol. Such a tool advantageously allows the efficient design and use of a process control system while ensuring that the physical characteristics of the system conform to the standard. In addition, the tool provides for more efficient diagnostics, on-line debugging, alarm monitoring and device maintenance.
TL;DR: An extensive suite of experiments with large sequential circuits confirm the robustness and efficiency of the proposed logic debugging methodology and suggest that Boolean satisfiability provides an effective platform for sequential logic debugging.
Abstract: Logic debugging of today's complex sequential circuits is an important problem. In this paper, a logic debugging methodology for multiple errors in sequential circuits with no state equivalence is developed. The proposed approach reduces the problem of debugging to an instance of Boolean satisfiability. This formulation takes advantage of modern Boolean satisfiability solvers that handle large circuits in a computationally efficient manner. An extensive suite of experiments with large sequential circuits confirm the robustness and efficiency of the proposed approach. The results further suggest that Boolean satisfiability provides an effective platform for sequential logic debugging.
TL;DR: In this article, techniques and systems for analysis, diagnosis, and debugging fabricated hardware designs at a Hardware Description Language (HDL) level are described, in particular related to design instrumentation circuitry that facilitates the analysis and diagnosis of the hardware designs.
Abstract: Techniques and systems for analysis, diagnosis and debugging fabricated hardware designs at a Hardware Description Language (HDL) level are described. In particular, the techniques and systems relate to design instrumentation circuitry that facilitates the analysis, diagnosis and debugging of the hardware designs. Although the hardware designs (which were designed in HDL) have been fabricated in integrated circuit products with limited input/output pins, the techniques and systems enable the hardware designs within the integrated circuit products to be comprehensively analyzed, diagnosed, and debugged at the HDL level at speed. The ability to debug hardware designs at the HDL level facilitates correction or adjustment of the HDL description of the hardware designs.
TL;DR: In this article, a new approach to locate and correct an erroneous statement in a function is presented, where the correct specification of the erroneous function is available in the form of preconditions and postconditions of the function.
Abstract: Software debugging is the activity of locating and correcting erroneous statements in programs. Automated tools to locate and correct the erroneous statements in a program can significantly reduce the cost of software development. In this paper, we present a new approach to locate and correct an erroneous statement in a function. We assume the correct specification of the erroneous function is available in the form of preconditions and postconditions of the function. Our approach combines ideas from software testing and weakest preconditions used in correctness proof methods to locate a likely erroneous statement. We have implemented our approach and conducted experiments with several small programs. In our experiments, our approach was able to locate the erroneous statements in a large number of cases. Our preliminary experimental results show that our approach has potential for development of an automated bug location and correction tool.