Refactoring certifié de programmes C

Transcription

Refactoring certifié de programmes C
L ABORATOIRE D ’I NFORMATIQUE DE N ANTES -ATLANTIQUE
UMR 6241
É COLE DOCTORALE STIM, N . 503
« Sciences et technologies
de l’information et des mathématiques »
Sujet de thèse pour 2016
Refactoring certifié de programmes C
Directeur de thèse
N OM, Prénom
: D OUENCE, Rémi
Équipe d’accueil
: Ascola
Unité de recherche
: LINA (UMR 6241)
Unité de rattachement
: Mines Nantes
Courriel
: Remi.Douence (at) mines-nantes.fr
Taux d’encadrement
: 50 %
Nombre de thèses en cours : 1
Co-encadrant
N OM, Prénom
: C OHEN, Julien
Unité de recherche
: Université de Nantes (Polytech)
Taux d’encadrement
: 50 %
Sujet de thèse pour 2016
Refactoring certifié de programmes C
Résumé. Les outils de refactorings disponibles actuellement ne sont pas corrects dans tous les cas
et les développeurs ne peuvent donc pas leur faire confiance. On s’intéresse ici à la construction
d’un outil de refactoring prouvé correct. L’outil manipulera des programmes C, ce langage étant
très utilisé dans l’industrie. On visera prioritairement les opérations de refactoring couramment
fournies par les outils standards (comme Eclipse) et on prendra comme cas d’application une
transformation complexe fondée sur une séquence d’opérations de refactoring atomiques, comme
une transformation d’architecture ou une désobfuscation. On s’intéressera aussi à l’élaboration de
stratégies dans l’assistant de preuve pour composer des opérations de refactoring.
Mots clés. Refactoring, langage C, assistant de preuve Coq, CompCert C, transformations de
programmes, remodularisation.
2
Introduction
Contexte et problématique
Les évolutions successives des logiciels tendent à dégrader la qualité de leur code
source [Leh96, HL05]. Ceci fait qu’au fil des évolutions, chaque modification devient
plus difficile et coûteuse à implanter.
Au bout d’un moment, ou parfois au fil des évolutions, on a besoin de modifier/corriger
la structure du programme, sans changer son comportement, afin de le ramener dans un
état où les évolutions à suivre auront une complexité et un coût raisonnable [ADD+ 10,
LML+ 15]. En développement agile, ceci fait partie intégrante du processus.
Malheureusement, les outils permettant de modifier la structure d’un code sans changer son comportement, que l’on appelle outils de refactoring, sont instables [Soa12].
En pratique, lorsqu’on utilise un tel outil pour faire une modification, on a toujours le
risque de tomber dans un cas que l’outil gère mal (il va modifier le comportement) et
on doit donc tester systématiquement le code modifié par l’outil, puis corriger les erreurs
introduites. Pour cette raison, les utilisateurs ne font pas confiance à ces outils et les
utilisent peu car ils pensent aller aussi vite en faisant toutes les modifications manuellement [SSS15, BS15].
Problèmes et opportunités
Le problème à résoudre est donc la fiabilité des implémentations des outils de refactoring.
La difficulté de concevoir et implémenter de tels outils fiables vient de la complexité des
langages ciblés qui fait que le nombre de cas particuliers à prendre en compte est très
grand. D’autres aspects rendent les transformations difficiles, comme le fait de devoir
préserver la “mise en page” et les commentaires, voire les directives de pré-processing du
code source.
On peut avoir une conception rigoureuse de l’outil tout en ayant des erreurs dans
son implémentation, comme c’est le cas pour Haskell Refactorer [LT05]. Donc un travail
théorique sur papier n’est pas suffisant pour garantir la qualité d’un outil de refactoring.
Des approches testées existent mais actuellement elles ont juste permis de révéler des dizaines d’erreurs dans les outils existants [Soa12] sans apporter d’aide aux
concepteurs pour les résoudre. Une approche “prouvé par construction” comme proposé
par [SEdM08] permettrait de résoudre ce problème. Ceci n’a pas été mis en place jusqu’à
présent probablement parce que les langages utilisés dans l’industrie ne disposent pas
d’une formalisation permettant de raisonner dessus (les formalisations existantes étaient
jusqu’à présent restreintes à un noyau du langage, comme Featherweight Java [IPW01]).
On trouve quelques travaux prouvés mais uniquement sur des micro-langages [ST08].
Or, à l’initiative du projet CompCert C [Ler15, BL09], on dispose maintenant d’une
sémantique complètement formalisée pour le langage C (au moins pour la norme MISRA
C actuellement utilisée dans l’industrie automobile). Cette formalisation s’appuie sur l’assistant de preuve Coq qui fournit des mécanismes puissants d’automatisation des raison3
nement ainsi qu’un générateur de code certifié. On peut donc envisager de construire des
outils de refactoring prouvés corrects (voir [Coh15]).
Travail demandé
Objectifs
L’objectif de cette thèse est de soutenir et développer l’utilisation des outils de refactoring en C. L’étude formelle de ces techniques permettra d’assurer la correction des
outils et fournira un cadre pour la génération d’opérations complexes par composition
d’opérations plus simples. L’approche sera validée par une étude de cas comme des transformations d’architecture ou un système de désobfuscation.
À l’issue de la thèse le doctorant aura acquis des compètences dans le domaine de la
formalisation et la preuve mécanisée de programmes. Le domaine de la certification de
programmes est en plein essor et sur la voie de la valorisation et du transfert industriel.
Le futur docteur aura aussi une connaissance fine de la sémantique du langage C et de
ses transformations de programmes.
Plan de travail prévisionnel de l’étude
Année 1 : État de l’art, implémentation et preuve d’une première opération.
• Établir une liste d’opérations traitées formellement dans la littérature et de
techniques employées (par exemple : [SDS+ 10, SK13]).
• Répertorier les transformations dont les programmeurs ont besoin.
• Identifier des transformations à grande échelle reposant sur une composition
d’opérations simples comme [Ker04, CDA12, ACR13].
• Étudier les raisons qui rendent ces opérations difficiles à implémenter correctement (par exemple interactions entre la construction syntaxique visée et
d’autres constructions du langage).
• Étudier les formalisations mécanisées de langages de portée industrielle existantes (CompCert C).
• Identifier des études de cas sur des applications existantes, comme des transformations d’architecture ou un système de désobfuscation.
Année 2 : Description d’une étude de cas et des opérations associées. Implémentation
d’une partie des opérations correspondantes.
On s’appuiera sur une étude de cas pour choisir un ensemble d’opérations de refactoring à implémenter et à prouver. On distinguera les opérations atomiques faisant
l’objet d’un développement complet des opérations composées dont l’implémentation et les propriétés s’obtiennent “gratuitement” [CA13].
4
• Définir formellement les transformations de programmes.
• Prouver ces transformations en Coq.
• Factoriser le processus du preuve sous la forme d’une bibliothéque de stratégies.
• Étudier dans quelle mesure le langage de tactiques de Coq peut être exploité
pour définir des stratégies de refactoring qui composent et enchaînent les opérations.
Année 3 : Finalisation des opérations et de l’étude de cas. Étude de la possibilité d’intégration à un environnement de développement industriel (Eclipse, Frama-C...).
Autres travaux possibles :
• Étudier la complémentarité entre la preuve et le test dans les systèmes certifiés
(toutes les parties de l’outil ne pouvant pas être prouvées).
• Étudier les formalisations du pré-processeur C [Vit03, Gar05, Pad09, Spi10]
et adapter l’outil de refactoring construit afin qu’il préserve les directives de
pré-traitement présentes dans les programmes.
Candidats
Compétences
• Compétences nécessaires : logique formelle, langages de programmation (C).
• Compétences appréciées : programmation fonctionnelle, sémantique des langages
de programmation, logique de Hoare, induction, assistants de preuve.
Déclarations de candidature et résultats universitaires connus
Pas de candidat retenu à ce jour.
5
Bibliographie
[ACR13]
A. Ajouli, J. Cohen, and J.-C. Royer. Transformations between composite and
visitor implementations in Java. In Software Engineering and Advanced Applications (SEAA), 2013 39th EUROMICRO Conference on, pages 25–32, Sept
2013.
[ADD+ 10] Nicolas Anquetil, Simon Denier, Stéphane Ducasse, Jannik Laval, Damien
Pollet, Roland Ducournau, Rodolphe Giroudeau, Marianne Huchard, JeanClaude König, and Abdelhak Djamel Seriai. Software (re)modularization :
Fight against the structure erosion and migration preparation, March 2010.
[BL09]
Sandrine Blazy and Xavier Leroy. Mechanized semantics for the Clight subset
of the C language. Journal of Automated Reasoning, 43(3) :263–288, 2009.
[BS15]
J. Brant and F. Steimann. Refactoring tools are trustworthy enough and trust
must be earned. Software, IEEE, 32(6) :80–83, Nov 2015.
[CA13]
Julien Cohen and Akram Ajouli. Practical use of static composition of refactoring operations. In Proceedings of the 28th Annual ACM Symposium on
Applied Computing, SAC ’13, pages 1700–1705. ACM, 2013.
[CDA12]
J. Cohen, R. Douence, and A. Ajouli. Invertible program restructurings for
continuing modular maintenance. In Software Maintenance and Reengineering
(CSMR), 2012 16th European Conference on, pages 347–352, March 2012.
[Coh15]
Julien Cohen. A Correct Refactoring Operation to Rename Global Variables
in C Programs. Research report, LINA-University of Nantes, December 2015.
https ://hal.archives-ouvertes.fr/hal-01248121.
[Gar05]
A. Garrido. Program refactoring in the presence of preprocessor directives.
PhD thesis, University of Illinois at Urbana-Champaign, Champaign, IL, USA,
2005.
[HL05]
Lorin Hochstein and Mikael Lindvall. Combating architectural degeneration :
a survey. Inf. Softw. Technol., 47 :643–656, July 2005.
6
[IPW01]
Atsushi Igarashi, Benjamin C. Pierce, and Philip Wadler. Featherweight Java :
a minimal core calculus for Java and GJ. ACM Trans. Program. Lang. Syst.,
23(3) :396–450, May 2001.
[Ker04]
Joshua Kerievsky. Refactoring to Patterns. Pearson Higher Education, 2004.
[Leh96]
M. M. Lehman. Laws of software evolution revisited. In 5th European
Workshop on Software Process Technology (EWSPT’96), volume 1149/1996
of LNCS, pages 108–124. Springer, Oct. 1996.
[Ler15]
Xavier Leroy.
CompCert C web page : http://compcert.inria.fr/
compcert-C.html, 2007–2015.
[LML+ 15] M. Leppanen, S. Makinen, S. Lahtinen, O. Sievi-Korte, A.-P. Tuovinen, and
T. Mannisto. Refactoring-a shot in the dark ? Software, IEEE, 32(6) :62–70,
Nov 2015.
[LT05]
Huiqing Li and Simon Thompson. Formalisation of Haskell Refactorings. In
Marko van Eekelen and Kevin Hammond, editors, Trends in Functional Programming, September 2005.
[Pad09]
Yoann Padioleau. Parsing C/C++ code without pre-processing. In Oege
de Moor and Michael I. Schwartzbach, editors, Compiler Construction, volume
5501 of Lecture Notes in Computer Science, pages 109–125. Springer Berlin
Heidelberg, 2009.
[SDS+ 10] Max Schäfer, Julian Dolby, Manu Sridharan, Emina Torlak, and Frank Tip.
Correct refactoring of concurrent Java code. In ECOOP 2010 – Object-Oriented
Programming, volume 6183 of Lecture Notes in Computer Science, pages 225–
249. Springer Berlin Heidelberg, 2010.
[SEdM08] Max Schäfer, Torbjörn Ekman, and Oege de Moor. Challenge proposal : Verification of refactorings. In Proceedings of the 3rd Workshop on Programming
Languages Meets Program Verification, PLPV ’09, pages 67–72, New York, NY,
USA, 2008. ACM.
[SK13]
Hemaiyer Sankaranarayanan and Prasad A Kulkarni. Source-to-source refactoring and elimination of global variables in c programs. Journal of Software
Engineering and Applications, 6(5) :264–273, 2013.
[Soa12]
Gustavo Soares. Automated behavioral testing of refactoring engines. In
Proceedings of the 3rd Annual Conference on Systems, Programming, and Applications : Software for Humanity, SPLASH ’12, pages 105–106, New York,
NY, USA, 2012. ACM.
[Spi10]
Diomidis Spinellis. CScout : A refactoring browser for C. Science of Computer
Programming, 75(4) :216–231, April 2010.
7
[SSS15]
T. Sharma, G. Suryanarayana, and G. Samarthyam. Challenges to and solutions for refactoring adoption : An industrial perspective. Software, IEEE,
32(6) :44–51, Nov 2015.
[ST08]
Nik Sultana and Simon Thompson. Mechanical Verification of Refactorings.
In Partial Evaluation and Program Manipulation. ACM, Jan. 2008.
[Vit03]
Marian Vittek. Refactoring browser with preprocessor. In Proceedings of
the Seventh European Conference on Software Maintenance and Reengineering,
CSMR ’03, pages 101–, Washington, DC, USA, 2003. IEEE Computer Society.
CV du directeur de thèse
Rémi Douence a soutenu une thèse sur la compilation des langages fonctionnels à l’Irisa
en 1996. Il a fait un post-doc à Carnegie-Mellon University, USA, sur l’analyse statique
de langages d’architecture logicielles en 1997. Il a été ingénieur expert à l’Irisa en 1998,
sur l’évaluation partielle de programmes C. Depuis, il est maître assistant aux Mines de
Nantes dans l’équipe Ascola. Il s’est intéressé aux langages de programmation : fonctionnels, d’architectures logicielles, réflexifs, de composants logiciels, d’aspects, de pilotage
de solveurs de contraintes, de composition de services. Il s’intéresse à la fois à l’expressivité de ces langages mais aussi à analyser ou garantir leur propriétés. Il a soutenu son
HDR en 2015.
CV du co-encadrant
Julien Cohen a soutenu une thèse dans le domaine des langages de programmation en
2004 à Évry, puis a été ATER à l’Univeristé de Paris-Sud – Orsay (laboratoire LRI). Il est
maître de conférences à Polytech Nantes depuis 2005 (laboratoire LINA). Il a encadré
une thèse soutenue en 2013 sur l’utilisation d’outils de refactoring pour implémenter
des transformations réversibles d’architectures (en Haskell et Java). Dans ce cadre, il a
développé et maintient toujours un plugin ajoutant plusieurs opérations de refactoring à
la plateforme IntelliJ IDEA pour Java. Il a prototypé récemment un outil de refactoring
pour CompCert C.
8