Neutral program variants are alternative implementations of a program, yet equivalent with respect to the test suite. Techniques such as approximate computing or genetic improvement share the intuition that potential for enhancements lies in these acceptable behavioral differences (e.g., enhanced performance or reliability). Yet, the automatic synthesis of neutral program variants, through program transformations remains a key challenge. This work aims at characterizing plastic code regions in Java programs, i.e., the code regions that are modifiable while maintaining functional correctness, according to a test suite. Our empirical study relies on automatic variations of 6 real-world Java programs. First, we transform these programs with three state-of-the-art program transformations: add, replace and delete statements. We get a pool of 23,445 neutral variants, from which we gather the following novel insights: developers naturally write code that supports fine-grain behavioral changes; statement deletion is a surprisingly effective program transformation; high-level design decisions, such as the choice of a data structure, are natural points that can evolve while keeping functionality. Second, we design 3 novel program transformations, targeted at specific plastic regions. New experiments reveal that respectively 60%, 58% and 73% of the synthesized variants (175,688 in total) are neutral and exhibit execution traces that are different from the original.
Context: Computational diversity, i.e., the presence of a set of programs that all perform compatible services but that exhibit behavioral differences under certain conditions, is essential for fault tolerance and security. Objective: We aim at proposing an approach for automatically assessing the presence of computational diversity. In this work, computationally diverse variants are defined as (i) sharing the same API, (ii) behaving the same according to an input-output based specification (a test-suite) and (iii) exhibiting observable differences when they run outside the specified input space. Method: Our technique relies on test amplification. We propose source code transformations on test cases to explore the input domain and systematically sense the observation domain. We quantify computational diversity as the dissimilarity between observations on inputs that are outside the specified domain. Results: We run our experiments on 472 variants of 7 classes from open-source, large and thoroughly tested Java classes. Our test amplification multiplies by ten the number of input points in the test suite and is effective at detecting software diversity. Conclusion: The key insights of this study are: the systematic exploration of the observable output space of a class provides new insights about its degree of encapsulation; the behavioral diversity that we observe originates from areas of the code that are characterized by their flexibility (caching, checking, formatting, etc.).
Product Derivation is a key activity in Software Product Line Engineering. During this process, derivation operators modify or create core assets (e.g., model elements, source code instructions, components) by adding, removing or substituting them according to a given configuration. The result is a derived product that generally needs to conform to a programming or modeling language. Some operators lead to invalid products when applied to certain assets, some others do not; knowing this in advance can help to better use them, however this is challenging, specially if we consider assets expressed in extensive and complex languages such as Java. In this paper, we empirically answer the following question: which product line operators, applied to which program elements, can synthesize variants of programs that are incorrect, correct or perhaps even conforming to test suites? We implement source code transformations, based on the derivation operators of the Common Variability Language. We automatically synthesize more than 370,000 program variants from a set of 8 real large Java projects (up to 85,000 lines of code), obtaining an extensive panorama of the sanity of the operations.
In this work, we characterize a new form of software diver- sity: the existence of a set of variants that (i) all share the same API, (ii) all behave the same according to an input- output based specification and (iii) exhibit observable dif- ferences when they run outside the specified input space. We quantify computational diversity as the dissimilarity be- tween execution traces on inputs that are outside the speci- fied domain. Our technique relies on test amplification. We propose source code transformations on test cases to explore the input domain and systematically sense the observation domain. We run our experiments on 472 variants of 7 classes from open-source, large and thoroughly tested Java classes. Our test amplification multiplies by ten the number of input points in the test suite and is effective at detecting software diversity.
A few works address the challenge of automating software diversification, and they all share one core idea: using automated test suites to drive diversification. However, there is is lack of solid understanding of how test suites, programs and transformations interact one with another in this process. We explore this intricate interplay in the context of a specific diversification technique called "sosiefication". Sosiefication generates sosie programs, i.e., variants of a program in which some statements are deleted, added or replaced but still pass the test suite of the original program. Our investigation of the influence of test suites on sosiefication exploits the following observation: test suites cover the different regions of programs in very unequal ways. Hence, we hypothesize that sosie synthesis has different performances on a statement that is covered by one hundred test case and on a statement that is covered by a single test case. We synthesize 24583 sosies on 6 popular open-source Java programs. Our results show that there are two dimensions for diversification. The first one lies in the specification: the more test cases cover a statement, the more difficult it is to synthesize sosies. Yet, to our surprise, we are also able to synthesize sosies on highly tested statements (up to 600 test cases), which indicates an intrinsic property of the programs we study. The second dimension is in the code: we manually explore dozens of sosies and characterize new types of forgiving code regions that are prone to diversification.
The predictability of program execution provides attackers a rich source of knowledge who can exploit it to spy or remotely control the program. Moving target defense ad- dresses this issue by constantly switching between many di- verse variants of a program, which reduces the certainty that an attacker can have about the program execution. The ef- fectiveness of this approach relies on the availability of a large number of software variants that exhibit dierent ex- ecutions. However, current approaches rely on the natural diversity provided by o-the-shelf components, which is very limited. In this paper, we explore the automatic synthe- sis of large sets of program variants, called sosies. Sosies provide the same expected functionality as the original pro- gram, while exhibiting dierent executions. They are said to be computationally diverse. This work addresses two objectives: comparing dierent transformations for increasing the likelihood of sosie synthe- sis (densifying the search space for sosies); demonstrating computation diversity in synthesized sosies. We synthesized 30 184 sosies in total, for 9 large, real-world, open source ap- plications. For all these programs we identied one type of program analysis that systematically increases the density of sosies; we measured computation diversity for sosies of 3 programs and found diversity in method calls or data in more than 40% of sosies. This is a step towards controlled massive unpredictability of software.
Web application development benefits massively from modular architectures and reuse. This excellent software engineering practice is also the source of a new form of monoculture in application-level co de, which creates a potential risk for dependability. Researchers propose using software diversification in multiple components of Web applications to reconcile the tension between reuse and dependability. This article identifies key enablers for the effective diversification of software, especially at the application-code level. It's possible to combine different software diversification strategies, from deploying different vendor solutions to fine-grained code transformations, to provide different forms of protection.
To improve software quality, rule checkers statically check if a software contains violations of good programming practices. On a real sized system, the alerts (rule violations detected by the tool) may be numbered by the thousands. Unfortunately, these tools generate a high proportion of "false alerts", which in the context of a specific software, should not be fixed. Huge numbers of false alerts may render impossible the finding and correction of "true alerts" and dissuade developers from using these tools. In order to overcome this problem, the literature provides different ranking methods that aim at computing the probability of an alert being a "true one". In this paper, we propose a framework for comparing these ranking algorithms and identify the best approach to rank alerts. We have selected six algorithms described in literature. For comparison, we use a benchmark covering two programming languages (Java and Smalltalk) and three rule checkers (Find Bug, PMD, Small Lint). Results show that the best ranking methods are based on the history of past alerts and their location. We could not identify any significant advantage in using statistical tools such as linear regression or Bayesian networks or ad-hoc methods.
Tools to detect coding standard violations in source code are commonly used to improve code quality. One of their original goals is to prevent bugs, yet, a high number of false positives is generated by the rules of these tools, i.e., most warnings do not indicate real bugs. There are empirical evidences supporting the intuition that the rules enforced by such tools do not prevent the introduction of bugs in software. This may occur because the rules are too generic and do not focus on domain specific problems of the software under analysis. We underwent an investigation of rules created for a specific domain based on expert opinion to understand if such rules are worthwhile enforcing in the context of defect prevention. In this paper, we performed a systematic study to investigate the relation between generic and domain specific warnings and observed defects. From our experiment on a real case, long term evolution, software, we have found that domain specific rules provide better defect prevention than generic ones.
Object-oriented applications of significant size are often complex and therefore, costly to maintain. Indeed, they rely on the concept of class which has low granularity with many implicit dependencies not always explicit. The component paradigm provides a projection space well-structured and of highest level for a better understanding through abstract architectural views. But it is possible to go further. It may also be the ultimate target of a complete process of re engineering. The end-to-end automation of this process is a subject on which literature has made very little attention. In this paper, we propose such a method to automatically transform an object-oriented application in an operational component-oriented application. We illustrate this method on a real Java application which is transformed in an operational OSGi application.
A system is complex and particularly difficult to understand and to maintain when it is described with a large number of highly interdependent parties. An object-oriented application is often complex because it uses hundreds or thousands of classes with many different dependencies more or less explicit. The same application, using the component paradigm, contains a smaller number of loosely coupled parties, highly cohesive with clear inter-dependencies. Indeed, because the component paradigm provides a high-level representation, synthetic and well-organized structure of complex systems, it can provide a space of projection for object-oriented applications. Such projection facilitates the step of understanding a system prior to any activity of maintenance and/or evolution. In addition, it is possible to use this representation as a model to perform a complete restructuring of an operational object-oriented application into its equivalent operational component-based application. Thus, the new form of the application benefits from all the good properties associated with the component-oriented paradigm. The goal of my thesis is to propose a semi-automatic approach to identify a component-based architecture in an object-oriented application. This architecture should help in understanding the original application, but also simplifies the projection of the object-oriented application on a concrete component model. The identification of a component-based architecture is achieved in three main steps : i) obtaining data for the identification process. These data, which correspond to dependencies between classes, are obtained with a dynamic analysis of the target application. ii) identification of the components. Three methods were explored. The first uses the formal concept analysis, the second two meta-heuristics and the last a multiobjective meta-heuristic. iii) identification of the component-based architecture representing the target application. This is done by identifying the provided and required interfaces for each component. To validate this identification process, and the different choices made during its development, I realized several case studies. Finally, I show the feasibility of the projection of the identified component-based architecture on a specific component model.
Coupling metrics play an important role in empirical software engineering research as well as in industrial measurement programs. The existing coupling metrics have usually been defined in a way that they can be computed from a static analysis of the source code. However, modern programs extensively use dynamic language features such as polymorphism and dynamic class loading that are difficult to capture by static analysis. Consequently, the derived metric values might not accurately reflect the state of a program. In this paper, we express existing definitions of coupling metrics using call graphs. We then compare the results of four different call graph construction algorithms with standard tool implementations of these metrics in an empirical study. Our results show important variations in coupling between standard and call graph-based calculations due to the support of dynamic features.
Software systems should evolve in order to respond to changing client requirements and their evolving environments. But unfortunately, the evolution of legacy applications generates an exorbitant cost. In this paper, we propose an approach to restructure legacy object-oriented applications into component-based applications. Our approach is based on dynamic dependencies between classes to identify potential components. In this way, the composition is dictated by the context of the application to improve its evolvability. We validate our approach through the study of three legacy Java applications.
Coupling metrics play an important role in empirical software engineering research as well as in industrial measurement programs. The existing coupling metrics have usually been defined in a way that they can be computed from a static analysis of the source code. However, modern programs extensively use dynamic language features such as polymorphism and dynamic class loading that are difficult to capture by static analysis. Consequently, the derived metric values might not accurately reflect the state of a program. In this paper, we express existing definitions of coupling metrics using call graphs. We then compare the results of four different call graph construction algorithms with standard tool implementations of these metrics in an empirical study. Our results show important variations in coupling between standard and call graph-based calculations due to the support of dynamic features.
We propose an approach for component candidate identification as a first step towards the extraction of component-based architectures from object-oriented programs. Our approach uses as input dynamic call graphs, built from execution traces corresponding to use cases. This allows to better capture the functional dependencies between classes. The component identification is treated as a clustering problem. To this end, we use formal concept analysis and design heuristics. We evaluate the feasibility of our approach on two programs. The obtained results are very satisfactory from both the performance and qualitative points of view.
A system is complex and particularly difficult to understand and to maintain when it is described with a large number of highly interdependent parties. An object-oriented application is often complex because it uses hundreds or thousands of classes with many different dependencies more or less explicit. The same application, using the component paradigm, contains a smaller number of loosely coupled parties, highly cohesive with clear inter-dependencies. Indeed, because the component paradigm provides a high-level representation, synthetic and well-organized structure of complex systems, it can provide a space of projection for object-oriented applications. Such projection facilitates the step of understanding a system prior to any activity of maintenance and/or evolution. In addition, it is possible to use this representation as a model to perform a complete restructuring of an operational object-oriented application into its equivalent operational component-based application. Thus, the new form of the application benefits from all the good properties associated with the component-oriented paradigm. The goal of my thesis is to propose a semi-automatic approach to identify a component-based architecture in an object-oriented application. This architecture should help in understanding the original application, but also simplifies the projection of the object-oriented application on a concrete component model. The identification of a component-based architecture is achieved in three main steps : i) obtaining data for the identification process. These data, which correspond to dependencies between classes, are obtained with a dynamic analysis of the target application. ii) identification of the components. Three methods were explored. The first uses the formal concept analysis, the second two meta-heuristics and the last a multiobjective meta-heuristic. iii) identification of the component-based architecture representing the target application. This is done by identifying the provided and required interfaces for each component. To validate this identification process, and the different choices made during its development, I realized several case studies. Finally, I show the feasibility of the projection of the identified component-based architecture on a specific component model.
Houari Sahraoui合作论文数department of computer science and operations research (GEODES, software engineering group) of University of Montreal3