Loading AI tools
Automatic repair of software bugs From Wikipedia, the free encyclopedia
Automatic bug-fixing is the automatic repair of software bugs without the intervention of a human programmer.[1][2][3] It is also commonly referred to as automatic patch generation, automatic bug repair, or automatic program repair.[3] The typical goal of such techniques is to automatically generate correct patches to eliminate bugs in software programs without causing software regression.[4]
Automatic bug fixing is made according to a specification of the expected behavior which can be for instance a formal specification or a test suite.[5]
A test-suite – the input/output pairs specify the functionality of the program, possibly captured in assertions can be used as a test oracle to drive the search. This oracle can in fact be divided between the bug oracle that exposes the faulty behavior, and the regression oracle, which encapsulates the functionality any program repair method must preserve. Note that a test suite is typically incomplete and does not cover all possible cases. Therefore, it is often possible for a validated patch to produce expected outputs for all inputs in the test suite but incorrect outputs for other inputs.[6] The existence of such validated but incorrect patches is a major challenge for generate-and-validate techniques.[6] Recent successful automatic bug-fixing techniques often rely on additional information other than the test suite, such as information learned from previous human patches, to further identify correct patches among validated patches.[7]
Another way to specify the expected behavior is to use formal specifications[8][9] Verification against full specifications that specify the whole program behavior including functionalities is less common because such specifications are typically not available in practice and the computation cost of such verification is prohibitive. For specific classes of errors, however, implicit partial specifications are often available. For example, there are targeted bug-fixing techniques validating that the patched program can no longer trigger overflow errors in the same execution path.[10]
Generate-and-validate approaches compile and test each candidate patch to collect all validated patches that produce expected outputs for all inputs in the test suite.[5][6] Such a technique typically starts with a test suite of the program, i.e., a set of test cases, at least one of which exposes the bug.[5][7][11][12] An early generate-and-validate bug-fixing systems is GenProg.[5] The effectiveness of generate-and-validate techniques remains controversial, because they typically do not provide patch correctness guarantees.[6] Nevertheless, the reported results of recent state-of-the-art techniques are generally promising. For example, on systematically collected 69 real world bugs in eight large C software programs, the state-of-the-art bug-fixing system Prophet generates correct patches for 18 out of the 69 bugs.[7]
One way to generate candidate patches is to apply mutation operators on the original program. Mutation operators manipulate the original program, potentially via its abstract syntax tree representation, or a more coarse-grained representation such as operating at the statement-level or block-level. Earlier genetic improvement approaches operate at the statement level and carry out simple delete/replace operations such as deleting an existing statement or replacing an existing statement with another statement in the same source file.[5][13] Recent approaches use more fine-grained operators at the abstract syntax tree level to generate more diverse set of candidate patches.[12] Notably, the statement deletion mutation operator, and more generally removing code, is a reasonable repair strategy, or at least a good fault localization strategy.[14]
Another way to generate candidate patches consists of using fix templates. Fix templates are typically predefined changes for fixing specific classes of bugs.[15] Examples of fix templates include inserting a conditional statement to check whether the value of a variable is null to fix null pointer exception, or changing an integer constant by one to fix off-by-one errors.[15]
Repair techniques exist that are based on symbolic execution. For example, Semfix[16] uses symbolic execution to extract a repair constraint. Angelix[17] introduced the concept of angelic forest in order to deal with multiline patches.
Under certain assumptions, it is possible to state the repair problem as a synthesis problem. SemFix[16] uses component-based synthesis.[18] Dynamoth uses dynamic synthesis.[19] S3[20] is based on syntax-guided synthesis.[21] SearchRepair[22] converts potential patches into an SMT formula and queries candidate patches that allow the patched program to pass all supplied test cases.
Machine learning techniques can improve the effectiveness of automatic bug-fixing systems.[7] One example of such techniques learns from past successful patches from human developers collected from open source repositories in GitHub and SourceForge.[7] It then use the learned information to recognize and prioritize potentially correct patches among all generated candidate patches.[7] Alternatively, patches can be directly mined from existing sources. Example approaches include mining patches from donor applications[10] or from QA web sites.[23]
Getafix[24] is a language-agnostic approach developed and used in production at Facebook. Given a sample of code commits where engineers fixed a certain kind of bug, it learns human-like fix patterns that apply to future bugs of the same kind. Besides using Facebook's own code repositories as training data, Getafix learnt some fixes from open source Java repositories. When new bugs get detected, Getafix applies its previously learnt patterns to produce candidate fixes and ranks them within seconds. It presents only the top-ranked fix for final validation by tools or an engineer, in order to save resources and ideally be so fast that no human time was spent on fixing the same bug, yet.
For specific classes of errors, targeted automatic bug-fixing techniques use specialized templates:
Comparing to generate-and-validate techniques, template-based techniques tend to have better bug-fixing accuracy but a much narrowed scope.[6][27]
There are multiple uses of automatic bug fixing:
In essence, automatic bug fixing is a search activity, whether deductive-based or heuristic-based. The search space of automatic bug fixing is composed of all edits that can be possibly made to a program. There have been studies to understand the structure of this search space. Qi et al.[30] showed that the original fitness function of Genprog is not better than random search to drive the search. Long et al.'s[31] study indicated that correct patches can be considered as sparse in the search space and that incorrect overfitting patches are vastly more abundant (see also discussion about overfitting below).
Sometimes, in test-suite based program repair, tools generate patches that pass the test suite, yet are actually incorrect, this is known as the "overfitting" problem.[32] "Overfitting" in this context refers to the fact that the patch overfits to the test inputs. There are different kinds of overfitting: incomplete fixing means that only some buggy inputs are fixed, regression introduction means some previously working features are broken after the patch (because they were poorly tested). Early prototypes for automatic repair suffered a lot from overfitting: on the Manybugs C benchmark, Qi et al.[6] reported that 104/110 of plausible GenProg patches were overfitting. In the context of synthesis-based repair, Le et al.[33] obtained more than 80% of overfitting patches.
One way to avoid overfitting is to filter out the generated patches. This can be done based on dynamic analysis.[34] Alternatively, Tian et al. propose heuristic approaches to assess patch correctness. [35][36]
Automatic bug-fixing techniques that rely on a test suite do not provide patch correctness guarantees, because the test suite is incomplete and does not cover all cases.[6] A weak test suite may cause generate-and-validate techniques to produce validated but incorrect patches that have negative effects such as eliminating desirable functionalities, causing memory leaks, and introducing security vulnerabilities.[6] One possible approach is to amplify the failing test suite by automatically generating further test cases that are then labelled as passing or failing. To minimize the human labelling effort, an automatic test oracle can be trained that gradually learns to automatically classify test cases as passing or failing and only engages the bug-reporting user for uncertain cases.[37]
A limitation of generate-and-validate repair systems is the search space explosion.[31] For a program, there are a large number of statements to change and for each statement there are a large number of possible modifications. State-of-the-art systems address this problem by assuming that a small modification is enough for fixing a bug, resulting in a search space reduction.
The limitation of approaches based on symbolic analysis[16][17] is that real world programs are often converted to intractably large formulas especially for modifying statements with side effects.
Benchmarks of bugs typically focus on one specific programming language. In C, the Manybugs benchmark collected by GenProg authors contains 69 real world defects and it is widely used to evaluate many other bug-fixing tools for C.[13][7][12][17]
In Java, the main benchmark is Defects4J now extensively used in most research papers on program repair for Java.[38][39] Alternative benchmarks exist, such as the Quixbugs benchmark,[40] which contains original bugs for program repair. Other benchmarks of Java bugs include Bugs.jar,[41] based on past commits.
Automatic bug-fixing is an active research topic in computer science. There are many implementations of various bug-fixing techniques especially for C and Java programs. Note that most of these implementations are research prototypes for demonstrating their techniques, i.e., it is unclear whether their current implementations are ready for industrial usage or not.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.