• Aucun résultat trouvé

Chapitre 3 Frama-C et PathCrawler

4.4 Le slicing

5 i n t i , len ; 60 //@ a s s e r t \ v a l i d ( s t r +0); 6 i f ( str [0] >=97 && str [0] <=122) 7 str [0] -=32; 8 i f ( str [0] < ’I ’ || str [0] > ’Z ’) 9 return; 10 i f ( strlen ( str ) != 12) 11 return; 12 len = strlen ( str ); 14 f o r ( i =1; i < len ; i ++){ 150 //@ a s s e r t \ v a l i d ( s t r+i ) ; 15 i f ( str [ i ] <48 || str [ i ] >57) 16 return ;}}

Figure 4.6 – Le programme de la figure 4.4 simplifi´e par rapport `a l’alarme `a la ligne 15

4.4

Le slicing

Le slicing [Wei81] est une technique de transformation de programmes qui permet d’ex- traire un sous-programme ex´ecutable, appel´e slice, `a partir d’un programme plus grand. Une slice a le mˆeme comportement que le programme original par rapport au crit`ere du slicing. Le slicing de Frama-C est bas´e sur l’analyse de d´ependance qui comprend le calcul du graphe de d´ependance de programme (PDG) [FOW87] montrant les relations de d´ependance entre les instructions du programme, et une analyse de d´ependance inter- proc´edurale permettant de traiter les appels de fonction. Le crit`ere classique du slicing est une paire compos´ee d’une instruction et d’un ensemble de variables du programme. Le slicing de Frama-C accepte d’autres crit`eres de slicing, par exemple un ensemble d’instructions.

Notons ;, la fermeture r´eflexive et transitive de la relation de d´ependance de donn´ees

ou de contrˆole. En d’autres termes, l1 ; l2 si l1 = l2, ou si l’ex´ecution de l2 d´epend de

l’ex´ecution de l1 (directement ou via des ´etats interm´ediaires). Cette relation n’est pas

sym´etrique : si l1 ;l2, cela n’implique pas que l2 ; l1. Par exemple pour les lignes 7 et

8 de la figure 4.3, nous avons 7 ; 8, mais nous n’avons pas 8 ; 7. Mais nous pouvons

avoir des d´ependances mutuelles l1 ; l2 et l2 ; l1 entre instructions. C’est le cas pour

les deux lignes 21 et 22 de la figure 4.3.

Nous d´esignons par labels(p) l’ensemble des ´etiquettes des instructions d’un programme p. Soit L un sous-ensemble de labels(p). Essentiellement, dans les techniques de slicing bas´e

sur les d´ependances (voir par exemple [RY88, Sec. 2.2] et [BBD+

10, d´efinition 4.6]), la

slice de p par rapport `a L, not´ee slice(p, L) ou pL, est d´efinie comme le sous-programme

de p contenant les instructions suivantes :

labels(pL) = { l ∈ labels(p) | ∃ l ′

∈ L, l ; l′

Pour un singleton L = {l}, la slice pL est ´egalement not´ee pl. Comme ; est r´eflexive,

L ⊆ labels(pL) et l ∈ labels(pl).

La slice d’un programme par rapport `a une alarme a est d´efinie comme ´etant la slice

par rapport `a l’instruction mena¸cante la de a, et on ´ecrit pa au lieu de pla. De mˆeme,

la slice d’un programme par rapport `a un ensemble d’alarmes A est d´efinie comme la

slice par rapport `a l’ensemble des instructions mena¸cantes de A, et on ´ecrit pA au lieu de

slice(p, {la| a ∈ A} ).

L’´etape du slicing produit une ou plusieurs versions simplifi´ees de p, chacune d’elles contenant un sous-ensemble d’alarmes qui peuvent ˆetre d´eclench´ees. Nous avons ´etudi´e et impl´ement´e cinq utilisations du slicing qui correspondent aux cinq options pr´esentes dans sante.

1. none : Le programme p est directement analys´e par analyse dynamique sans aucune simplification par le slicing.

2. all : Le slicing est appliqu´e une fois et le crit`ere de simplification est l’ensemble de toutes les alarmes de p. Nous obtenons une version simplifi´ee contenant les mˆemes menaces que le programme original p. Ensuite, l’analyse dynamique est appliqu´ee `a cette version simplifi´ee.

3. each : Soit n le nombre d’alarmes dans p. Le slicing est effectu´e n fois, une fois par rapport `a chaque alarme ai, produisant n programmes simplifi´es p1, p2, . . . , pn.

Ensuite, l’analyse dynamique est appel´ee n fois pour analyser les n programmes simplifi´es.

4. min : On s´electionne des sous-ensembles d’alarmes A1, A2, . . . , Ak de A tels que

A1 ∪ A2 ∪ . . . ∪ Ak = A avec k ≤ n. L’op´eration de slicing est effectu´ee k fois

pour A1, A2, . . . , Ak. Ainsi k programmes simplifi´es pA1, pA2, . . . , pAk sont produits. Ensuite, l’analyse dynamique est appel´ee k fois pour analyser les k programmes r´e- sultants pAi.

5. smart : Cette option applique l’option min it´erativement en r´eduisant la taille des sous-ensembles quand c’est n´ecessaire.

Les trois premi`eres options (none, all et each) sont les options de base. Elles sont pr´esent´ees en d´etail dans la partie 4.6. min et smart sont des options plus avanc´ees, qui se basent sur une analyse de d´ependances entre les alarmes pr´esent´ee en partie 4.7. Les options min et smart sont d´etaill´ees en partie 4.8.

Pour le programme en figure 4.4, le programme simplifi´e qui pr´eserve toutes les alarmes est pr´esent´e dans la figure 4.5. Afin de faciliter la comparaison avec la version initiale,

4.4. Le slicing les parties ray´ees montrent le code enlev´e par le slicing et les parties non ray´ees corres- pondent au code du programme simplifi´e. Un autre programme simplifi´e est donn´e par la figure 4.6. Il pr´esente la version simplifi´ee par rapport `a l’alarme `a la ligne 15. On notera que le code restant a ´et´e l´eg`erement simplifi´e par suppression des initialisations de i et de len et par suppression des valeurs retourn´ees. On constate que la slice par rapport `a une seule alarme est plus simple que celle relative `a toutes les alarmes.

Certaines propri´et´es du slicing utilisent une s´emantique `a base des trajectoires finies

que nous pr´esentons bri`evement dans la partie 4.4.1, en s’inspirant de [BBD+10].

4.4.1

S´emantique `a base de trajectoires

Un ´etat est une fonction totale qui associe une valeur `a chaque variable. Une valeur non d´efinie est not´ee ⊥. La restriction d’un ´etat `a un ensemble de variables V , not´ee par s ↓ V , est d´efinie par :

(s ↓ V )x =

(

s(x) si x ∈ V,

⊥ sinon.

Une s´equence non vide T = (l1, s1)(l2, s2) . . . (lk, sk) . . . de couples (instruction, ´etat)

est appel´ee trajectoire de p si, `a partir d’un ´etat d’entr´ee s1, le programme p ex´ecute la s´e-

quence d’instructions l1, l2, . . . , lk, . . . o`u li est l’´etiquette de la i-`eme instruction ex´ecut´ee

et si est l’´etat avant l’ex´ecution de li. On dit aussi que T est la trajectoire du programme

p `a partir de l’´etat d’entr´ee s1.

On dit que U est une trajectoire partielle de T si U est finie et T commence avec U. En d’autres termes, les trajectoires partielles de T sont les pr´efixes finis de T . Ils ont la forme suivante :

(l1, s1)(l2, s2) . . . (lm, sm), m ≥ 1.

Soit M ⊆ labels(p) un ensemble d’´etiquettes de p. La restriction d’un ´el´ement de trajectoire (l, s) sur M est d´efinie comme suit :

(l, s) ↓ M =

(

(l, s ↓ ref(l)) si l ∈ M,

ε sinon,

o`u ref(l) est l’ensemble des variables lues `a l’instruction l et ε est la s´equence vide.

Pour une trajectoire T = (l1, s1) . . . (lk, sk) . . ., la projection de T sur M est d´efinie

par :

ProjM(T ) = (l1, s1) ↓ M . . . (lk, sk) ↓ M . . .

0 void e u r o c h e c k( char * str ){ 5 i n t i , len ; 60 //@ a s s e r t \ v a l i d ( s t r +0); 61 i f (0 >= length ( str )) 62 error (); 63 e l s e 6 i f ( str [0] >=97 && str [0] <=122) 7 str [0] -=32; 8 i f ( str [0] < ’I ’ || str [0] > ’Z ’) 9 return ; 10 i f ( strlen ( str ) != 12) 11 return ; 12 len = strlen ( str ); 14 f o r ( i =1; i < len ; i ++){ 150 //@ a s s e r t \ v a l i d ( s t r+i ) ; 151 i f ( i >= length ( str )) 152 error (); 153 e l s e 15 i f ( str [ i ] <48 || str [ i ] >57) 16 return ;}}

Figure 4.7 – Le programme simplifi´e par rapport `a l’alarme `a la ligne 15 auquel ont ´et´e ajout´ees les branches d’erreurs

Proposition 4.4.1 (Propri´et´es du slicing)

Soit L un ensemble d’instructions dans p, pL la slice de p par rapport `a l’ensemble d’ins-

tructions L et s0 un ´etat d’entr´ee pour p. Soit T et T′ respectivement les trajectoires de p

et pL ex´ecut´ees `a partir de l’´etat d’entr´ee s0.

(a) labels(pL) est inclus dans labels(p).

(b) Si U est une trajectoire partielle de T , alors il existe une trajectoire partielle U′

de T′

telle que les projections de U et U′

sur L sont ´egales : ProjL(U) = ProjL(U

).

Documents relatifs