cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006
-
14 juil. 2006 à 02:39
cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006
-
29 juil. 2006 à 20:39
Bonjour à tous,
j'utilise Splint pour analyser mon code C et je souhaite que le résultat de l'analyse me dise les failles de gestion mémoire du genre (les codes suivants sont triviaux et seulement pour tester les capacités de Splint),:
int *pointeur;
pointeur = malloc(10*sizeof(int));
pointeur[15] = 3;
free(pointeur);
Comme on le sait, ce code passe à la compilation mais provoque des erreurs à l'exécution. C'est pourquoi le mieux est de le détecter avant.
Splint me dit bien qu'il y a une possibilité que pointeur soit NULL, là impécable, je suis d'accords, il faut donc ajouter un if(!NULL) avant d'utiliser le pointeur et Splint ne détecte alors aucun pb de gestion mémoire à cet endroit.
Mais ce que je veux c'est qu'il m'indique que la ligne pointeur[15] = 3; provoque un déppassement, comme il le fait si j'utilise des tableau (dans la vraie vie, on ne trouvera pas, j'espère, une erreur de codage comme ce qui suit ) :
int tableau[10];
tableau[15] = 3;
dans cet exemple, Splint m'indique bien qu'il y a dépassement car 15 est plus grand que 10-1.
mais Splint ne semble pas comprendre ce que je lui dis.
Quelqu'un à t'il une idée de comment faire ?
Est-ce possible avec Splint ? Sur www.splint.org, ils disent que ca peut ce faire mais ne disent pas comment.
Existe-t-il un analyseur statique qui sache le faire ?
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 14 juil. 2006 à 17:45
"Comme
on le sait, ce code passe à la compilation mais provoque des erreurs à
l'exécution. C'est pourquoi le mieux est de le détecter avant".
Je ne vois pas ce qui cloche mis à part que si on l'essaye d'acceder au 15eme int d'un tableau qui en a que 10, cela provoque des segment faults. Pourquoi veux tu utiliser ce logiciel, un cerveau normalement constitué déctecte ce genre de bétises...
"dans cet exemple, Splint m'indique bien qu'il y a dépassement car 15 est plus grand que 10-1", ne crois pas qu'en déclarant un tableau de 10 int tu ne peut en écrire que 9 et OBLIGATOIREMENT laisser le dernier à 0x0, le caractère NULL final c'est simplement une convention pour determiner la fin des chaines de char. Rien ne t'empeche de faire pointeur[9]=0x123;
cs_JCDjcd
Messages postés1138Date d'inscriptionmardi 10 juin 2003StatutMembreDernière intervention25 janvier 20094 14 juil. 2006 à 18:34
Il y a mieux que "Splint", et cela s'applle "DEBUG" ...
C'est la premiere fois que je vois un logiciel de ce type ! C'est honteux car totalement inutile ! Dans la pluspart des cas on fait pas mallco(10) mais plutot malloc(n) auquel cas "Splint" ne pourra RIEN dire !!!
De plus pourquoi perdre du temps a "analyser" le code au lieu de remonter ses manches et faire du pas-a-pas ... ?!?
Pourquoi faire simple quand on peut faire compliqué ?
cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006 15 juil. 2006 à 02:53
Desole pour les accents pas dispo sur ce clavier.
Comme je l'ai indique dans l'introduction de mon 1er message, les codes sont triviaux et ne sont la que pour l'exemple, pour tester Splint avant de le pousser dans ses retranchements. Bien sur que si je code un malloc(10) et que l'instruction suivante est pointeur[15], je suis bon pour aller me coucher ou alors c'est que j'ai bien arrose le repas du midi!!! Maintenant, il est claire que on utilise plutot un malloc(n), ce que test egalement les analyseurs de code.
Je suis tres etonne de vos remarques... entendre dire qu'un analyseur de code c'est honteux :) c'est pareil q'un medecin qui refuse de faire des electrocadiogrammes sous pretexte qu'en ecoutant le coeur battre pendant 2 heures, on arrive au meme diagnostique.
Ca fait 8 ans que je bosse pour l'aeronautique ou pour l'aerospatiale et ce genre de soft d'analyse statique ou dynamique sont obligatoire pour respecter les normes de securite.En plus, le code est relu par une autre equipe, tout comme la documentation qui est verifiee par 3 personnes differentes avant d'etre validee.
Oui on peut verifier le code a la main, et c'est d'ailleur toujours ce qu'on fait. Bien sur on test en debug, mais tu te vois tester en debug , a la main, un soft qui doit gerer plus de 1000 entrees differentes? Tu peux mais tu mettras combien de temps pour tester toutes les combinaisons ? Et surtout, personne n'est a l'abris de l'erreur humaine!
Je te fais un exemple tres simple pour bien saisir le probleme : tu pense que je vais dire au familles des disparus apres un crash d'avion que je suis desole mais j'avais pourtant teste le soft en debug et que tout passait???
Bref, pour un logiciel maison, on se passe de ce genre d'analyseurs. Pour un soft embarque dans une machine a laver, c'est pas tres grave non plus, a part que je serai tres fache que la machine m'a bouffe toutes mes chaussettes et le codeur se fera surement virer car ca coutera un max a athur martin en SAV. Mais pour des applications comme l'aeronautique, ou encore les centrales nucleaire, c'est un autre problemmes, tu me suis ?
En conclusion, pour des logiciels tres complexes ou a risques, les analyseurs de codes sont utilises, tout comme les automates de test de type mercury...
Vous n’avez pas trouvé la réponse que vous recherchez ?
steve_clamage
Messages postés475Date d'inscriptiondimanche 3 octobre 2004StatutMembreDernière intervention11 août 20065 15 juil. 2006 à 10:56
En effet, tester tout les branchments d'un programme en avec un
debugger peut etre long, alors qu'avec l'analyse automatique du code on
repere tout de suite des erreurs detectable statiquement, seulement ca
ne suffit pas.
cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006 15 juil. 2006 à 20:35
L'utilisation d'analyseur de code n'est seulement en dernière vérification pour être un peu plus sur, en espérant être certain :), qu'on a bien éliminé tous les bugs en relecture et en debug. C'est donc une vérification suplémentaire qui permet d'assurer une classe de sécurité plus élevée.
Splint, n'est pas utilisé en aéronautique car il n'offre pas les preuves de sa validation. En gros, il n'est pas validé par une organisation de type ISO et autres.
Je ne sais pas si le problème que je rencontre est dû a un bug de splint, je ne l'ai pas trouvé dans la liste.
J'ai essayé avec /*@ensures maxSet(pointeur) == (10-1) @*/ mais ca ne détecte toujours pas.
J'utilise la commande suivante : splint.exe +bounds buffer.c >essai.txt
Pour Microsoft, c'est un autre débat, oui, ils utilisent des analyseurs statiques, dynamiques, des automates de test... mais je ne pense pas que les codeurs soient si nul que ca, non. Je pencherais plutôt pour dire que premièrement Microsoft doit faire du bénéfice et que les choix marketing, commerciaux et financier ont trop souvent été malheureux, au détriment de la technique.
C'est le fameux triptique coût-durée-technique, tout est lié. Ce genre de considérations n'est pas présent pour linux, en tout cas par rapport au coût, puisque le codeur est "gratuit" et que l'argent que quelques sociétés arrivent à gagner grâce à linux ne se fait uniquement qu'à faveur des services offerts (installation, configuration, formations, développement particuliers...).
En second, et pour sortir du debat windows-linux, dans les secteurs à risque (pour la vie humaine), ont utilisera ni l'un, ni l'autre mais d'autres OS, un peu plus blindés au niveaux de leur validation (et qui peuvent le démontrer sur le papier avec une norme de type ISO ou autre et avec leur expérience).
CG85
Messages postés30Date d'inscriptionvendredi 2 janvier 2004StatutMembreDernière intervention10 février 2010 29 juil. 2006 à 08:42
(C'est un peu HS mais bon)
@adrienj : > Ca fait 8 ans que je bosse pour l'aeronautique ou pour l'aerospatiale
Il me semblait que c'était Ada ou un autre langage fortement typé et non le C qui était employé pour des applications sensibles ?
cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006 29 juil. 2006 à 20:27
Ca dépend de l'application, du calculateur, si c'est du militaire ou non et de la classe de sécurité.
Mais pour l'aviation civile, c'est le plus souvent du C. Pour l'aviation militaire, c'est plus de l'ADA.
cs_adrienj
Messages postés7Date d'inscriptionlundi 27 février 2006StatutMembreDernière intervention29 juillet 2006 29 juil. 2006 à 20:39
Pour eviter toutes confusions, voici une petite precision :
splint est un analyseur statique de code. En gros, il analyse le
code a la maniere du compilateur en allant plus loin. Il indique bien
plus de types de warning qu'un compilateur comme gcc par exemple. Bien
souvent, pour aider splint, il faut anoter le code, en indiquant par
exemple qu'un pointeur a le droit d'etre nul en argument de fonction,
ou pour indiquer la valeur max que devrait avoir un index parcourant un
tableau...
Cependant, l'analyse statique a des limites, celles du statisme
justement. On ne peut pas aller aussi loin dans l'analyse qu'en
runtime. Mais, au meme titre que de prendre en compte les warnings du
compilateur, c'est un outil qui va plus loin dans la securite aussi
bien au niveau de la structure que de la precision du code. Et puis
j'ajouterai formateur.
Voici deux articles qui en parlent (en anglais) :
https://pse.cheme.cmu.edu/wiki/view/Ascend/StaticCodeAnalysis qui nous parle de trois approches pour le debug statique du code
avec les bons et les mauvais côtés : ne pas s'occuper des warnings du
compilateur, les prendre en compte et faire les modifications en
consequence ou debusquer encore plus de warnings en utilisant splint.
Postula : tester tous les chemins possibles en runtime est
difficile. Quand un bug est mis en évidance, il peut être difficilement
localisable dans les sources. Autre cas : tester un logiciel
communiquant avec un instrument ou périphérique sans ce dernier est
problématique.
L'analyse statique peut apporter des solutions à ces problèmes :
- tous les chemins d'exécution peuvent être analysés sans exécuter le programme ;
- découvrir la racine éxacte du problème qui peut alors être aisément supprimé ;
mais aussi ses manques :
- l'analyse heuristique peut être imprécise ;
- il peut y avoir des warnings qui ne le sont pas vraiment (l'analyse suit rigoureusement la norme C ANSI) ;
- détecter 100% des erreurs est théoriquement impossible ;
- elle demande quelques fois que le dévoloppeur ajoute des anotations dans le code pour guider l'analyse.
Une liste de logiciels d'analyse statique :
- FlawFinder, ITS4, RATS : analyse lexicale : exemple, va toujours
donner une warning sur un strcpy sans se soucier des arguments (à la
différence d'un strncpy).
- Splint : analyse sémantique : exemple, peut analyser la taille
et le type des argument d'un strcpy pour indiquer ou non un warning,
mais nécessite l'aide d'anotations dans certain cas.
- Sparse : je ne le connais pas mais c'est un analyseur statique
qu'avait développé initialement Linus Torvalds pour déboguer le noyaux
de Linux.
- Cqual, Csur, CCured : pas testés.
"Tu te serviras fréquemment de lint et ses dires tu étudiras avec
attention, parce qu'en vérité sa perception et son jugement souvent
dépassent les tiens."
-Henry Spencer, "Les dix commandements du programmeur C"
Lire ce court article http://www.linux-kheops.com/doc/lgazette/issue-51/lg51-fr-6.html,
paru sur le site de la distribution linux-kheops qui nous parle de
l'analyse statique et surtout de lint et LcLint (nomé maintenant
splint).
Comme dit l'article en conclusion, "Lint, et tout
particulièrement une version aussi puissante que LCLint, peut être
utilisé pour en apprendre plus sur la programmation du langage C. Le
simple fait de réfléchir sur les messages d'erreur et tenter de les
faire disparaître vous en donnera un bon apperçu."
Voir également de livre de Peter van der Linden, "Expert C programming - Deep C secrets", qui en parle également.
J'essais d'évaluer splint en le poussant dans ses
retranchements, afin de connaitre réellement les limites de l'analyse
statique et de ce logicel en particulier.
Voici un nouveau test sous splint pour la détection de dépassement mémoire:
void FillBuffer(int *piBuffer)
{
int i;
for(i=0;i<10;i++)
piBuffer[i] = 3;
}
int main (void)
{
int tiTableau[5];
FillBuffer(tiTableau);
return 0;
}
Ici Splint ne détecte qu'il y a possibilité de dépassement mémoire,
au niveau de la boucle for de la fonction FillBuffer. On peut se dire
alors que ca marche ! Mais, en remplacant le 10 par 5, Splint ne
devrait alors ne pas signaler de bug de dépassement mémoire. Or, splint
m'indique toujours qu'il y a possibilité de dépassement mémoire.
C'est là que les anotations spéciales de splint entrent en jeux.
J'insère cette anotation : /*@requires maxSet(piBuffer) >= 4@*/,
pour indiquer à Splint que le que le pointeur piBuffer doit avoir une
taille d'au moins 5 (de 0 à 4)
Ce qui donne :
void FillBuffer(int *piBuffer)
/*@requires maxSet(piBuffer) >= 4@*/
{
int i;
for(i=0;i<5;i++)
piBuffer[i] = 3;
}
int main (void)
{
int tiTableau[5];
FillBuffer(tiTableau);
return 0;
}
Splint ne m'indique plus la possibilité de dépassement de mémoire. Ca marche !
Par contre, si je retourne à mon 1er test, en remplacant 5 par 10
dans la condition de la boucle for, alors splint m'indique bien qu'il y
a possibilité de dépassement mémoire.
Dans ce cas précis, Splint arrive donc à détecter le dépassement mémoire mais nécessite un coup de main : l'anotation du code.