Maison  >  Article  >  Opération et maintenance  >  Étude de cas de Google sur la création d'outils d'analyse de code statique

Étude de cas de Google sur la création d'outils d'analyse de code statique

WBOY
WBOYavant
2023-06-05 22:22:591210parcourir

Les bugs logiciels coûtent beaucoup de temps et d’argent aux développeurs et aux éditeurs de logiciels. En prenant 2014 comme exemple, un bug (« goto fail ») dans la mise en œuvre du protocole SSL largement utilisé a entraîné l'acceptation de certificats SSL invalides, et un autre bug lié au formatage de la date a provoqué des pannes de service généralisées sur Twitter. De telles erreurs peuvent souvent être détectées par analyse statique. En fait, elles peuvent être rapidement identifiées lors de la lecture du code ou de la documentation, et la réalité finale est que la situation se produit toujours dans l'environnement de production.

Des travaux antérieurs ont bien rendu compte de l'expérience de l'application d'outils de détection de bogues au développement de logiciels. Mais bien qu'il existe de nombreux cas de réussite de développeurs utilisant des outils d'analyse statique, il existe toujours les raisons suivantes pour lesquelles les ingénieurs ne sont pas toujours disposés à utiliser des outils d'analyse statique ou à ignorer activement les informations d'avertissement générées par les outils :

  • Pas correctement intégré . L'outil n'est pas intégré au workflow du développeur ou le programme prend trop de temps à s'exécuter

  • Alertes invalides ; Les informations d'alerte ont une faible faisabilité ;

  • ne sont pas dignes de confiance. Les utilisateurs ne font plus confiance aux résultats en raison de faux positifs.

  • Le scénario réel d'utilisation du défaut n'est pas clair. Le bug signalé est théoriquement réalisable, mais le défaut n'est pas clair dans les scénarios d'utilisation réels

  • Le coût de la réparation est trop élevé ; La correction des défauts de code détectés est trop coûteuse ou risquée 

  • Les alertes sont difficiles à comprendre ; Les utilisateurs ne comprennent pas les informations spécifiques et les principes des informations d'alarme.

L'article suivant décrit comment nous avons tiré les leçons de l'expérience et des leçons précédentes de Google dans l'utilisation de FindBug pour l'analyse du langage Java et la littérature académique, et avons finalement réussi à construire une architecture d'infrastructure d'analyse statique pour une utilisation quotidienne par les ingénieurs logiciels de Google. Grâce à la contribution des ingénieurs, les outils de Google peuvent détecter des milliers de problèmes que les ingénieurs résolvent chaque jour avant que le code problématique ne soit fusionné dans les référentiels de code à l'échelle de l'entreprise.

En termes de portée des outils, nous nous concentrons sur l'intégration de l'analyse statique dans le processus de développement de base de Google et servons la majorité des développeurs Google. De nombreux outils d'analyse de code statique seront éclipsés par les 2 milliards de lignes de code déployées chez Google. La technologie permettant d'exécuter des analyses complexes dans des scénarios à grande échelle n'est donc pas une priorité élevée.

Bien sûr, il faut tenir compte du fait que les développeurs extérieurs à Google travaillant dans des domaines professionnels (tels que les domaines de l'aérospatiale et des équipements médicaux) peuvent utiliser des outils et des flux de travail d'analyse statique spécifiques. De plus, les développeurs dont les projets de développement impliquent des types spécifiques (tels que le code du noyau et les pilotes de périphériques) peuvent nécessiter des méthodes d'analyse spécifiques. Il y a eu de nombreux excellents résultats en analyse statique. Nous ne pensons pas que les expériences et les idées que nous avons rapportées soient uniques, mais nous croyons fermement qu'il est bénéfique d'organiser et de partager notre travail pour améliorer la qualité du code et l'expérience de développement de Google. .

Définition des termes. Nous utilisons la définition suivante du terme : Un outil d'analyse exécute un ou plusieurs « vérificateurs » sur le code source et identifie les « défauts » pouvant présenter des pannes logicielles. Si un développeur ne prend pas de mesures proactives après avoir constaté un problème, nous considérons qu'il s'agit d'un « véritable faux positif » s'il rencontre une faille identifiée et n'apporte pas les correctifs appropriés. Si l'analyse statique n'identifie pas avec précision une faille signalée, mais que le développeur prend des mesures proactives pour modifier le code afin d'améliorer la lisibilité et la maintenabilité, alors il ne s'agit pas d'un « faux positif » valide. Si une analyse signale une erreur de code réelle, mais que le développeur n'a pas compris le problème de code et n'a pris aucune mesure, cela est considéré comme un « véritable faux positif ». Nous utilisons cette distinction conceptuelle pour souligner l’importance de la perspective R&D. Le développeur, et non l'auteur de l'outil, perçoit et affecte directement le taux de faux positifs de l'outil.

Comment Google compile et construit des logiciels

Ci-dessous, nous décrirons les points clés du processus de développement logiciel de Google. Chez Google, presque tous les outils de développement (sauf les environnements de développement) sont centralisés et standardisés. De nombreuses parties de l'infrastructure sont construites avec Scratch et appartiennent à des équipes internes, conservant ainsi la flexibilité nécessaire pour être expérimentales.

Contrôle du code source et propriété du code. Google a développé et utilise un système de gestion de code à source unique. Et expérimentez avec une seule branche stockant (presque) tout le code propriétaire de Google. Les développeurs utilisent une approche de développement « basée sur les troncs » qui limite les branches, souvent divisées par versions plutôt que par fonctionnalités. Tout ingénieur peut modifier n'importe quel code avec l'approbation du propriétaire du code. La propriété du code est basée sur les chemins ; le propriétaire d'un répertoire a les mêmes autorisations sur les sous-répertoires.

Construction du système. Tout le code de la base de code Google est compilé avec une version de Bazel indépendante de la compilation, ce qui signifie que toutes les entrées doivent être explicitement déclarées et stockées dans le contrôle de source pour faciliter la distribution et la parallélisation de la construction. Les règles Java du système de build de Google s'appuient sur le JDK et le compilateur Java contrôlé par la source, et ces binaires peuvent être mis à jour pour tous les utilisateurs en introduisant rapidement de nouvelles versions. Les builds proviennent généralement de la source (via head) et ont rarement des composants binaires archivés dans des branches. Étant donné que tous les développeurs utilisent le même système de construction, n'importe quel code peut être compilé avec succès sans erreur.

Outils d'analyse. Les outils d'analyse statique utilisés par Google ne sont généralement pas complexes. L'infrastructure de Google ne prend pas en charge l'exécution d'analyses d'intégrité inter-procédurales ou basées sur un programme sur les systèmes à ce niveau, et n'utilise pas non plus de techniques d'analyse statique avancées (telles que la technologie de logique de séparation) à grande échelle. Même un simple vérificateur nécessite une infrastructure d'analyse pour prendre en charge l'intégration dans le flux de travail. Les types d'analyseurs qui ont été déployés dans le cadre du processus de développement général comprennent : Les vérificateurs de style (tels que Checkstyle, Pylint et Golint) ; tels que Error Prone, ClangTidy, Clang Thread SafetyAnalysis, Govet et CheckerFramework), y compris, mais sans s'y limiter, des outils de correspondance de modèles d'arbre de syntaxe abstraite, des vérificateurs basés sur le type et un analyseur de détection d'appels manqués pour les variables.

  • Appeler l'analyseur du service de production (par exemple vérifier si l'employé mentionné dans le commentaire du code travaille toujours chez Google) ;

  • # 🎜🎜#
  • Vérifiez les propriétés de la sortie de build (telles que la taille du binaire de sortie).

  • Le linter C++ de Google peut détecter la vulnérabilité "goto fail", qui vérifie s'il y a des parenthèses après l'instruction if. Un vérificateur basé sur la correspondance de modèles aurait identifié des erreurs de formatage de date, de sorte que le code qui a provoqué le crash de Twitter n'aurait pas été compilé par Google. Les développeurs de Google utilisent également des outils d'analyse dynamique tels que AddressSanitizer pour rechercher les vulnérabilités du tampon et ThreadSanitizer pour détecter les problèmes de course aux données. Ces outils s'exécutent pendant les tests et parfois même dans des environnements avec du trafic de production.

    Environnement de Développement Intégré (IDE). Le point d’entrée pour les problèmes d’analyse statique au début du processus de développement doit être intégré dans l’EDI. Mais les développeurs Google utilisent une grande variété d'éditeurs, il est donc difficile de détecter systématiquement les erreurs de tous les développeurs avant d'appeler l'outil de génération. Bien que Google utilise des analyses intégrées aux IDE internes populaires, exiger un IDE spécifique capable d'analyser est un chemin long et ardu.
  • Testez. Presque tout le code Google contient des liens de test correspondants, des tests unitaires aux tests d'intégration à grande échelle. Les activités de tests sont les premiers concepts à intégrer dans la construction du système. Tout comme le lien de compilation, elles sont indépendantes et distribuées. Pour la plupart des projets, les développeurs écrivent et gèrent les cas de test pour le code ; les projets ne disposent généralement pas d'un groupe de test ou d'assurance qualité distinct.

    Le système de génération et de test continu de Google exécutera des tests à chaque fois que le code est soumis et fournira des commentaires en temps opportun sur les échecs de construction ou les cas de test qui échouent en raison des modifications du code des développeurs. Il prend également en charge le test des modifications avant de les valider pour éviter de rompre les dépendances du projet.
Revue de code. Chaque code soumis à Google sera d'abord soumis à l'examen du code. Bien que n'importe quel développeur puisse apporter des modifications à n'importe quelle partie du code de Google, le propriétaire du code doit examiner et approuver les modifications avant de les soumettre pour fusion. De plus, même les propriétaires de code doivent revoir leur code avant de valider les modifications. Les révisions de code sont effectuées via un outil Web centralisé étroitement intégré à d’autres infrastructures de développement. Les résultats de l'analyse statique peuvent être affichés dans les revues de code.

Sortie de code. Les équipes de Google publient fréquemment des versions, et la majeure partie du processus de vérification et de déploiement des versions est automatisée via des méthodes « push on green », ce qui signifie qu'il est difficile de s'appuyer sur le processus laborieux de vérification manuelle des versions. Si un ingénieur Google découvre un bug en production, une nouvelle version peut être annulée et déployée sur les serveurs de production à un coût relativement faible par rapport à une interruption du service.

Learning from FindBugs

Dès les premières étapes d'exploration et de recherche de 2008 à 2010, la technologie d'analyse statique de Google s'est concentrée sur l'utilisation de FindBug pour l'analyse Java : par l'outil indépendant de l'Université du Maryland créé par William Pugh et David Hovemeyer du York College, Pennsylvanie. Le principe est d'analyser les fichiers de classes Java compilés et d'en extraire les modèles de structure de code pouvant provoquer des bugs. Depuis janvier 2018, FindBugs n'est utilisé comme outil de ligne de commande que par un très petit nombre d'ingénieurs chez Google. Une petite équipe de Google appelée "BugBot" a travaillé avec l'auteur original Pugh et a fait trois tentatives majeures pour intégrer FindBugs dans le processus de développement de Google.

Nous avons appris les points suivants en essayant :

Essayez 1 : Tableau de bord des bugs. Initialement en 2006, FindBugs a été intégré dans un outil centralisé pour analyser l'intégralité de la base de code de Google chaque nuit, en enregistrant les résultats pour que les ingénieurs puissent les visualiser via le tableau de bord. Bien que FindBugs ait trouvé des centaines d'erreurs dans la base de code Java de Google, le tableau de bord a eu peu d'effet car le tableau de bord des messages d'erreur était séparé du processus de développement quotidien et ne pouvait pas être intégré aux autres résultats d'analyse statique existants.

Tentative 2 : Concentrez-vous sur l'amélioration des bugs.

Ensuite, l'équipe BugBot a commencé à classer manuellement les nouveaux problèmes trouvés chaque nuit et à identifier et traiter les rapports de bugs relativement importants. En mai 2009, des centaines d'ingénieurs de Google ont participé à une semaine « Fix it » à l'échelle de l'entreprise, axée sur la résolution des alertes FindBugs. Au total, 3 954 alertes ont été examinées (42 % sur un total de 9 473), mais seulement 16 % (640) ont été corrigées. En fait, 44 % des résultats rapportés (1 746) ont été soumis au suivi des bogues. Bien que la campagne Fixit ait confirmé que bon nombre des problèmes détectés par FindBugs étaient de véritables défauts de code, un grand nombre d'entre eux n'étaient pas suffisamment importants pour justifier de véritables correctifs. Il est difficile de classer manuellement les problèmes et de soumettre des rapports de bogues dans un environnement à grande échelle.

Tentative 3 : Intégrer dans la révision du code. Ensuite, l'équipe BugBot a intégré et implémenté un tel système : lorsque le réviseur est informé que la révision est en attente, FindBugs s'exécutera automatiquement et les résultats de l'analyse seront affichés sous forme de commentaires pour la révision du code. L'équipe de révision du code ci-dessus a déjà implémenté le système. normes de codage/problèmes de style Terminer. Les développeurs de Google peuvent ignorer les faux positifs et filtrer les résultats de FindBugs pour plus de crédibilité. L'outil tente en outre d'afficher uniquement les nouvelles alertes FindBugs, mais les traite parfois comme de nouveaux problèmes en raison d'une classification incorrecte. Lorsque l'outil de révision de code a été remplacé en 2011, cette intégration a pris fin, pour deux raisons : les taux élevés de faux positifs dans la pratique ont fait perdre confiance aux développeurs dans l'outil, et la liberté des développeurs de personnaliser le filtrage a amené toutes les parties à remettre en question l'analyse. . Les résultats sont incohérents.

Incorporé au processus de compilation

Parallèlement à l'expérience FindBugs, le processus de développement C++ de Google a continué de s'améliorer en ajoutant de nouvelles règles de vérification au compilateur Clang. L'équipe Clang a mis en œuvre un nouveau vérificateur de compilateur, comprenant des informations de recommandation de correctifs, a utilisé ClangMR pour exécuter une vérification d'optimisation du compilateur mise à jour sur l'ensemble de la base de code Google dans une approche distribuée et a codé des correctifs d'implémentation pour les bogues existants dans la question de la base de code. Une fois que la base de code a été marquée avec des problèmes résolus, l'équipe Clang applique un nouveau vérificateur pour signaler les nouveaux problèmes comme des erreurs du compilateur (au lieu d'avertissements, que l'équipe Clang a découvert que les développeurs de Google ignoreraient) pour abandonner la construction, qui doit être résolue. passer. L'équipe Clang a très bien réussi à améliorer la qualité de la base de code grâce à cette stratégie.

Nous avons suivi cette idée et construit un outil d'analyse statique Java simple et facile à utiliser basé sur l'analyse de modèles appelé Error Prone basé sur le compilateur javac. La première règle de contrôle introduite s'appelle PreconditionsCheckNotNull, qui est utilisée pour détecter si le paramètre d'entrée de détection de méthode est vide au début de l'exécution du programme, comme checkNotNull ("uid est nul", uid) au lieu de checkNotNull (uid, "uid était nul").

Pour lancer un vérificateur comme PreconditionsCheckNotNull sans interrompre aucune build consécutive, l'équipe Error Prone l'utilise pour exécuter de telles vérifications sur l'ensemble de la base de code à l'aide d'un programme MapReduce basé sur javac, analogue à ClangMR, en utilisant une build FlumeJava appelée JavacFlume. JavacFlume générera une série de suggestions de correctifs, comparera les différences, puis appliquera ces correctifs à l'ensemble de la base de code. L'équipe Error Prone utilise l'outil interne Rosie pour diviser les modifications de code à grande échelle en modifications plus petites, chaque modification n'affectera qu'un seul projet, testera ces modifications et les enverra à l'équipe appropriée pour révision du code. Les équipes examinent uniquement les correctifs qui s'appliquent à leur code, et ce n'est que si leur inclusion est approuvée que Rosie validera les modifications réelles. En fin de compte, toutes les réparations et modifications apportées aux problèmes existants ont été approuvées et tous les défauts existants ont été résolus. L'équipe a officiellement ouvert la méthode d'erreur du compilateur.

Lorsque nous avons interrogé les développeurs qui ont reçu ces correctifs, 57 % de ceux qui ont reçu les correctifs intégrés au code étaient heureux de recevoir de telles informations, et 41 % étaient neutres. Seulement 2 % des personnes ont réagi négativement et ont déclaré : « Cela ne fera qu'augmenter ma charge de travail ».

La valeur des vérifications du compilateur

Les erreurs de compilation sont affichées dès le début du processus de développement et intégrées dans le flux de travail du développeur. Nous avons constaté que l'extension du vérificateur de compilation améliorait efficacement la qualité du code chez Google. Étant donné que les vérifications dans Error Prone sont écrites en interne sur l'arbre de syntaxe abstraite de javac plutôt que sur le bytecode (contrairement à FindBugs), les développeurs extérieurs à l'équipe peuvent effectuer des vérifications relativement facilement. Tirer parti de ces contributions externes est essentiel pour accroître l’impact global d’Error Prone. En janvier 2018, 162 auteurs avaient contribué à 733 contrôleurs.

Plus tôt vous signalerez un problème, mieux ce sera

Le système de build centralisé de Google enregistre tous les processus de build et les résultats de build, nous garantissons donc que tous les utilisateurs peuvent voir les messages d'erreur dans la fenêtre de temps spécifiée. Nous avons envoyé une enquête aux développeurs qui avaient récemment rencontré une erreur de compilation et aux développeurs qui avaient reçu des recommandations pour un correctif pour le même problème. Les développeurs de Google estiment que les problèmes signalés au moment de la compilation (par opposition aux correctifs fusionnés dans le code) détectent des bogues plus importants ; par exemple, les participants à l'enquête pensaient que 74 % des problèmes étaient signalés comme de « vrais problèmes » au moment de la compilation, alors que seulement 21 % des problèmes étaient signalés au moment de la compilation. des problèmes ont été trouvés dans le code fusionné. De plus, les participants à l'enquête ont évalué 6 % des problèmes détectés au moment de la compilation (contre 0 % lors de la phase de fusion) comme « critiques ». Ce résultat peut s'expliquer par « l'effet de biais de survie » ; c'est-à-dire que les bogues sont plus susceptibles d'être détectés par des moyens plus coûteux (tels que les tests et les révisions de code) au moment de la soumission du code. Forcer autant de contrôles que possible dans le compilateur est un moyen sûr d'éviter ces coûts.

Standards pour les vérifications du compilateur

Afin d'étendre notre travail, car interrompre la compilation sera une action plus importante, nous avons défini l'activation des vérifications dans le compilateur. La norme est définie sur strict mode d'étiquetage élevé. Les vérifications du compilateur sur Google doivent être simples à lire, exploitables et faciles à corriger (si possible, les messages d'erreur doivent inclure des suggestions de correctifs généralement implémentables) ; ne produire aucun faux positif valide (les actions d'analyse ne doivent pas interrompre les builds qui sont réellement correctes) ; code); et signalez uniquement les bogues authentiques plutôt que les problèmes de style ou de conventions de codage. L'objectif principal de la mesure des analyseurs qui répondent à ces critères n'est pas simplement de détecter les problèmes, mais de corriger automatiquement ces erreurs du compilateur dans l'ensemble de la base de code. Mais ces normes limitent également la portée des contrôles que l'équipe Error Prone peut effectuer lors de la compilation du code ; de nombreux problèmes qui ne peuvent pas être détectés avec précision ou universellement résolus sont toujours des problèmes auxquels nous sommes confrontés.

Afficher des messages d'avertissement pendant la phase de révision du code

Une fois que l'équipe Error Prone a construit l'infrastructure nécessaire pour détecter les problèmes au moment de la compilation et a prouvé que cette approche fonctionne, nous J'espère trouver davantage de bogues à fort impact qui ne se limitent pas à la vérification des erreurs du compilateur que nous effectuons et fournir des résultats d'analyse pour des langages autres que Java et C++. Le deuxième point d'entrée d'intégration pour les résultats de l'analyse statique est l'outil de révision de code de Google : les résultats de l'analyse statique sont affichés dans Critique, la plateforme d'analyse de programme de Google, à l'aide de Tricorder. Depuis janvier 2018, les versions C++ et Java de Google ne comportent aucune erreur de compilation, et tous les résultats d'analyse apparaissent dans les erreurs du compilateur ou pendant la phase de révision du code.

Standards pour les vérifications de révision de code

Contrairement aux vérifications au moment de la compilation, les résultats d'analyse affichés lors de la révision de code permettent un taux de faux positifs effectif allant jusqu'à 10 %. Les retours attendus lors des révisions de code ne sont pas toujours parfaits et les développeurs doivent évaluer les correctifs proposés avant de les adopter. Les vérificateurs de Google lors de la phase d'audit du code doivent répondre aux critères suivants :

Facile à comprendre. C'est clair et facile à comprendre pour les ingénieurs

La solution est réalisable et facile à résoudre. Les correctifs peuvent nécessiter plus de temps, de réflexion et d'efforts que la phase de vérification du compilateur, et les résultats de la vérification doivent inclure des conseils sur la façon de qualifier le problème

Un taux de faux positifs effectif inférieur à 10 % ; . Les développeurs doivent avoir le sentiment que le vérificateur trouve des bogues réels au moins 90 % du temps ;

a un impact significatif sur la qualité du code. Les problèmes détectés n'empêchent peut-être pas le programme de fonctionner correctement, mais les développeurs doivent les prendre au sérieux et choisir de les résoudre.

Certains problèmes sont suffisamment graves pour être signalés dans le compilateur, mais travailler dessus mais les réduire ou développer des correctifs automatiques n'est pas réalisable. Par exemple, la résolution de certains problèmes peut nécessiter une refactorisation du code. L'activation de ces vérifications en cas d'erreurs du compilateur nécessiterait un nettoyage manuel de l'implémentation existante, ce qui n'est pas réalisable sur une base de code aussi volumineuse que celle de Google. Les outils d'analyse montrant ces vérifications dans les révisions de code évitent d'introduire de nouveaux problèmes, permettant ainsi aux développeurs de décider s'ils doivent prendre des mesures pour apporter les correctifs appropriés. Les révisions de code sont également un bon moment pour signaler des problèmes relativement sans importance, tels que des problèmes de spécification ou de simplification du code optimisé. D'après notre expérience, le reporting pendant la phase de compilation est toujours difficile à accepter pour les développeurs et rend plus difficile l'itération et le débogage rapide. Par exemple, un détecteur de chemins de code inaccessibles peut gêner un bloc de code pour le débogage. Mais lors d’une revue de code, les développeurs se préparent soigneusement à terminer leur code ; ils sont dans un état d’esprit réceptif, plus réceptif aux questions de lisibilité et de détails de style.

Tricorder

Tricorder est conçu pour être facilement extensible et prend en charge de nombreux types différents d'outils d'analyse de programme, y compris des outils d'analyse statique et dynamique. Nous montrons certains vérificateurs sujets aux erreurs dans Tricorder qui ne peuvent pas être activés en tant qu'erreurs du compilateur. Error Prone a également créé un nouvel ensemble de composants d'analyse C++ qui s'intègrent à Tricorder appelé ClangTidy. Les rapports de l'analyseur Tricorder prennent en charge les résultats dans plus de 30 langages, prennent en charge une analyse syntaxique simple telle que les vérificateurs de style, exploitent les informations du compilateur pour Java, JavaScript et C++ et peuvent être intégrés directement aux données de production (par exemple, des informations sur l'affectation des tâches en cours d'exécution). Tricorder continue de connaître du succès chez Google car il s'agit d'un modèle de plug-in qui prend en charge une plate-forme écologique pour les rédacteurs d'analyseurs, met en évidence les correctifs réalisables pendant le processus de révision du code et fournit un canal de rétroaction pour améliorer l'analyseur et garantir que les développeurs d'analyseurs prennent des mesures sur retour positif.

Permettez aux utilisateurs de contribuer. Depuis janvier 2018, Tricorder comprend 146 analyseurs, dont 125 extérieurs à l'équipe Tricorder, et sept systèmes de plugins pour des centaines de contrôles supplémentaires (tels que ErrorProne et ClangTidy), soit deux).

Les évaluateurs interviennent pour suggérer des correctifs.

Le vérificateur Tricorder peut fournir des outils de révision de code avec des suggestions de réparation raisonnables visibles pour les réviseurs de code et les développeurs. Les réviseurs peuvent demander aux développeurs de corriger le code défectueux en cliquant sur le bouton « Veuillez corriger » dans les résultats de l'analyse. Les réviseurs n’approuvent généralement pas l’inclusion des modifications de code tant que tous leurs commentaires (manuels et découverts automatiquement) n’ont pas été traités.

Itérer sur les commentaires des utilisateurs. En plus du bouton « Veuillez corriger », Tricorder fournit également un bouton « inutile » sur lequel les évaluateurs ou les proposants peuvent cliquer pour indiquer qu'ils ne sont pas d'accord avec les résultats de l'analyse. L'action de clic soumettra automatiquement le bogue dans le outil de suivi des bogues et le dirigera vers l'équipe à laquelle appartient l'analyseur. L'équipe Tricorder assure le suivi de ces clics "inutiles" et calcule le ratio de clics entre les clics "veuillez corriger" et les clics "inutiles". Si le ratio de l'analyseur dépasse 10 %, l'équipe Tricorder désactivera l'analyseur jusqu'à ce que l'auteur l'améliore. Bien que l'équipe Tricorder désactive rarement les analyseurs de manière permanente, elle a désactivé certains analyseurs (dans quelques scénarios) jusqu'à ce que les auteurs de l'analyseur aient supprimé et modifié les vérificateurs qui se sont révélés encombrants et inutiles.

Les bogues soumis améliorent souvent les performances de l'analyseur, augmentant ainsi considérablement la satisfaction des développeurs à l'égard de ces analyseurs ; par exemple, l'équipe Error Prone a développé une vérification en 2014 qui signale lorsque trop de paramètres sont transmis dans Guava transmis à une fonction comme printf. Les fonctions de type Printf n'acceptent pas réellement tous les spécificateurs printf, seulement %S. Environ une fois par semaine, l'équipe Error Prone recevra un bug "stupide" affirmant que l'analyse est incorrecte et que le nombre de caractères génériques de format dans le code de correspondance de bug correspond en réalité au nombre d'arguments réellement passés. Lorsque l'utilisateur tente de transmettre un espace réservé générique autre que %s, l'analyseur est en réalité incorrect dans tous les cas. L'équipe a donc modifié le texte de description de l'inspection du code pour indiquer directement que la fonction n'accepte que les espaces réservés %s et a cessé de recevoir des erreurs concernant cette vérification.

Échelle d'utilisation du Tricorder. Depuis janvier 2018, Tricorder avait analysé environ 50 000 modifications de révision de code par jour. L'analyse est effectuée trois fois par seconde pendant les heures de pointe. Les évaluateurs cliquent sur « Veuillez réparer » plus de 5 000 fois par jour et les auteurs appliquent des solutions de réparation automatique environ 3 000 fois par jour. L'analyseur Tricorder reçoit un retour de 250 clics "inutiles" par jour.

Le succès de l’analyse de révision de code montre qu’elle occupe le « point idéal » dans le flux de travail des développeurs de Google. Les résultats d'analyse affichés au moment de la compilation doivent être d'une qualité et d'une précision relatives qui ne peuvent être obtenues en s'appuyant sur l'analyseur pour continuer à identifier des problèmes graves. Une fois les révisions et le code fusionnés, les développeurs sont confrontés à une résistance accrue à apporter des modifications. En conséquence, les développeurs ont du mal à apporter des modifications au code qui a déjà été testé et publié et sont moins susceptibles de résoudre des problèmes à faible risque et moins importants. De nombreux autres projets d'analyse dans des organisations de développement de logiciels (tels que Facebook Infer Analytics pour les applications Android/iOS) mettent également l'accent sur la révision du code comme point d'entrée clé pour rapporter les résultats d'analyse.

Extended Analyzer

À mesure que les développeurs de Google acceptent les résultats de l'analyseur Tricorder, ils continuent de demander d'autres extensions à l'analyseur. Tricorder résout ce problème de deux manières : en permettant la personnalisation au niveau du projet et en ajoutant les résultats de l'analyse de la présentation à d'autres étapes du processus de développement. Dans cette section, nous discutons également de certaines des raisons pour lesquelles Google n'a pas encore exploité des analyses plus sophistiquées comme processus de développement de base.

Personnalisation au niveau du projet

Tous les analyseurs demandés n'ont pas la même valeur dans l'ensemble de la base de code Google ; par exemple, certains analyseurs sont associés à des taux de faux positifs plus élevés, donc un vérificateur avec un taux de faux positifs correspondant peut être requis. La configuration est valable uniquement lorsqu'il est activé dans un projet spécifique. Ces profileurs ne sont utiles qu’aux bonnes équipes.

Afin de répondre à ces besoins, notre objectif est de rendre Tricorder personnalisable. Notre expérience précédente en matière de personnalisation de FindBugs était moins efficace ; la personnalisation au niveau de l'utilisateur entraînait une différenciation au sein et entre les équipes et une diminution de l'utilisation des outils. Étant donné que chaque utilisateur peut voir une vue différente d'un problème, il n'existe aucun moyen de garantir que toutes les personnes travaillant sur le même projet puissent voir un problème spécifique. Si un développeur supprime toutes les importations inutilisées du code de son équipe, même si un autre développeur n'est pas cohérent dans la suppression des importations inutilisées, la modification sera rapidement rejetée par la restauration.

Pour éviter de tels problèmes, Tricorder autorise uniquement la configuration au niveau du projet, garantissant que toute personne apportant des modifications à un projet spécifique voit une vue cohérente des résultats d'analyse liés à ce projet. Le maintien de la cohérence dans la vue des résultats permet à plusieurs types d'analyseurs d'effectuer les actions suivantes :

Produire des résultats binaires. Par exemple, Tricorder inclut un analyseur pour les définitions de tampons de protocole qui identifie les modifications rétrocompatibles. Ceci est utilisé par les équipes de développeurs pour garantir la persistance des informations dans les tampons de protocole sous forme sérialisée, mais est ennuyeux pour les équipes qui ne stockent pas les données sous cette forme. Un autre exemple est que les analyseurs suggèrent d'utiliser des implémentations de code Guava ou Java qui n'ont pas de sens pour les projets qui ne peuvent pas utiliser ces bibliothèques ou fonctionnalités de langage ;

nécessite une configuration spécifique ou des annotations dans le code. Par exemple, les équipes ne peuvent utiliser que la nullité du Checker Framework pour analyser si leur code est correctement annoté. Un autre analyseur qui, lorsqu'il est correctement configuré, vérifiera la croissance de la taille binaire et du nombre d'appels de fonction d'un binaire Android spécifique, et avertira les développeurs si la croissance est attendue ou si elle approche de la limite ;

#🎜🎜 #Prise en charge des langages spécifiques au domaine (DSL) et des directives de codage spécifiques à l'équipe. Certaines équipes de développement de logiciels de Google ont développé des petits DSL et souhaitent exécuter des vérificateurs associés. D'autres équipes ont mis en œuvre les meilleures pratiques en matière de lisibilité et de maintenabilité et souhaitent continuer à appliquer ces contrôles tout en étant très gourmandes en ressources. Un cas d'analyse mixte basée sur les résultats de l'analyse dynamique incluse. Une telle analyse apporte une grande valeur à certaines équipes, mais est trop coûteuse ou prend trop de temps pour tout le monde.

En janvier 2018, il existe environ 70 analyses facultatives au sein de Google, avec 2 500 projets permettant d'en activer au moins une. Des dizaines d'équipes au sein de l'entreprise développent activement de nouveaux analyseurs, la plupart affiliés en dehors du groupe des outils de développement.

Autres points d'intégration des flux de travail

À mesure que la confiance des développeurs dans ces outils augmente, ils exigent également une intégration plus poussée dans leurs flux de travail. Tricorder fournit désormais des résultats d'analyse en fournissant des outils de ligne de commande, des systèmes d'intégration continue et des outils de révision de code.
Support en ligne de commande. L'équipe Tricorder a ajouté la prise en charge de la ligne de commande pour les développeurs, qui sont essentiellement des gestionnaires de code et parcourent et nettoient fréquemment diverses analyses d'alerte dans la base de code de l'équipe. Ces développeurs connaissent également très bien les types de correctifs que chaque analyseur produira et ont un degré élevé de confiance dans un analyseur spécifique. Ainsi, les développeurs peuvent utiliser des outils de ligne de commande pour appliquer automatiquement tous les correctifs dans une analyse donnée et apporter des modifications propres ;

seuil de validation du code. Certaines équipes souhaitent que des analyseurs spécifiques bloquent les validations de code plutôt que de simplement apparaître dans les outils de révision de code. Généralement, les demandes visant à bloquer les validations sont effectuées par des équipes dotées de vérificateurs hautement personnalisés qui garantissent l'absence de faux positifs, souvent dans des DSL ou des bibliothèques personnalisées.

Le code montre le résultat. Les présentations de code sont idéales pour montrer l'ampleur des problèmes dans les grands projets (ou dans des bases de code entières). Par exemple, les résultats d'analyse lors de la navigation dans le code d'une API obsolète peuvent montrer la quantité de travail nécessaire pour migrer ; ou certaines analyses de sécurité et de confidentialité sont globales et nécessitent qu'une équipe professionnelle examine les résultats avant de déterminer s'il y a un problème. Étant donné que les résultats de l'analyse ne sont pas affichés par défaut, Code Browser permet à des équipes spécifiques d'activer des vues d'analyse, puis d'analyser l'intégralité de la base de code et d'examiner les résultats sans distraire les autres développeurs de ces analyseurs. Si les résultats de l'analyse sont associés à un correctif, le développeur peut appliquer le correctif en cliquant simplement sur l'outil de navigation dans le code. Code Browser est également idéal pour afficher les résultats d'analyse de l'utilisation des données de production, car ces données ne sont pas disponibles tant que le code n'est pas validé et exécuté.

Analyse complexe

Toutes les analyses statiques largement déployées chez Google sont relativement simples, bien que certaines équipes effectuent des analyses inter-procédurales avec des cadres d'analyse spécifiques au projet ciblant des domaines spécifiques (par exemple, les applications Android). L'analyse des processus à l'échelle de Google est techniquement réalisable. Mais une telle analyse est très difficile à mettre en œuvre. Comme mentionné ci-dessus, tout le code Google est stocké dans un référentiel de code source global distinct, donc conceptuellement, tout code du référentiel de code peut faire partie de n'importe quel fichier binaire. Il est donc concevable d'imaginer une situation dans laquelle les résultats d'analyse d'une revue de code spécifique nécessiteraient une analyse de l'ensemble du référentiel de code. Alors que Infer de Facebook se concentre sur l'analyse inter-procédurale, en adaptant les analyseurs basés sur une logique divisée à des bases de code de plusieurs millions de lignes, l'adaptation d'un tel analyseur aux référentiels de codes de plusieurs milliards de lignes de Google nécessite encore des efforts d'ingénierie importants. Depuis janvier 2018, la mise en œuvre d'un système d'analyse plus sophistiqué n'est pas une priorité pour Google :

Investissement important. L'investissement initial dans les infrastructures sera prohibitif ;

Des efforts seront nécessaires pour réduire les taux de fausses alarmes. Les équipes d'analyse doivent développer des techniques pour réduire considérablement le taux de faux positifs pour de nombreux analyseurs et/ou limiter strictement les messages d'erreur affichés, comme le fait Figureinfer

Il reste encore beaucoup à mettre en œuvre. Les équipes d'analyse disposent toujours d'analyseurs plus « faciles » à mettre en œuvre et à intégrer ;

Coûts initiaux élevés. Nous trouvons que cet analyseur « simple » est très rentable, ce qui est l'une des principales motivations de FindBugs. En comparaison, le coût initial est élevé, même lorsqu’il s’agit de déterminer le retour sur investissement des contrôleurs plus sophistiqués.

Veuillez noter que ce retour sur investissement peut varier considérablement pour les développeurs extérieurs à Google qui travaillent dans des domaines spécialisés (tels que l'aérospatiale et les dispositifs médicaux) ou sur des projets spécifiques (tels que les pilotes de périphériques et les applications mobiles).

Insights

Notre expérience en essayant d'intégrer l'analyse statique dans les flux de travail Google nous a appris les précieuses leçons suivantes :

Trouver des bugs est facile. Lorsqu’une base de code est suffisamment grande, elle contient presque tous les modèles de code imaginables. Même dans les bases de code matures avec une couverture de test complète et des processus rigoureux de révision du code, les bugs sont importants. Parfois, les problèmes ne sont pas évidents lors d’une inspection locale, et parfois des erreurs sont introduites par des refactorisations apparemment inoffensives. Par exemple, considérons l'extrait de code suivant utilisant le champ f de type long,

result =
31 * result

  • (int) (f ^ (f >>> 32));

imaginez ensuite ce qui se passe si le développeur change le type de f en int. Le code continue de se compiler, mais le décalage droit de 32 devient une opération sans opération, le champ est XOR avec lui-même et la valeur de hachage de la variable devient une constante 0. Le résultat est que f n'affecte plus la valeur générée par la méthode hashCode. Tout outil capable de calculer le type de f peut détecter correctement le bon décalage de plus de 31, nous avons corrigé le code 31 dans la base de code de Google avec cette erreur, et avons également inclus la vérification dans la compilation dans l'erreur du serveur Error Pone.

Étant donné que la détection des erreurs est facile, Google utilise des outils simples pour détecter les types d'erreurs. Ensuite, le rédacteur d'analyse effectue des réglages précis en fonction des résultats de l'exécution du code Google.

La plupart des développeurs n'utilisent pas les outils d'analyse statique autant qu'ils le pensent. Comme pour le développement de nombreux outils commerciaux, Google s'est initialement appuyé sur la mise en œuvre de FindBugs. Les ingénieurs ont choisi d'accéder à un tableau de bord centralisé pour visualiser les problèmes rencontrés dans leurs projets, mais peu d'entre eux l'ont réellement vu de cette façon. Il est trop tard pour trouver des bogues qui ont été incorporés dans le code (qui peuvent avoir été déployés et exécutés sans que les utilisateurs ne s'en aperçoivent). Pour garantir que la plupart ou la totalité des ingénieurs voient les avertissements d'analyse statique, l'outil d'analyse doit être intégré au flux de travail et activé par défaut pour tout le monde. Des projets tels que Error Prone ne fournissent pas de tableau de bord des erreurs, mais étendent le compilateur avec des vérificateurs supplémentaires et affichent les résultats de l'analyse lors de la révision du code.

Les sentiments des développeurs sont cruciaux. D'après notre expérience et notre accumulation de matériaux, de nombreuses tentatives visant à intégrer l'analyse statique dans les organisations de développement de logiciels ont échoué. Les ingénieurs ne sont généralement pas autorisés par la direction de Google à utiliser des outils d'analyse statique. Les ingénieurs travaillant sur l'analyse statique doivent démontrer leur impact avec des données valides du monde réel. Pour qu’un projet d’analyse statique réussisse, les développeurs doivent percevoir qu’ils en bénéficient et apprécier la valeur de son utilisation.

Pour créer une plateforme d'analyse performante, nous construisons des outils qui offrent une grande valeur aux développeurs. L'équipe Tricorder examinera attentivement les problèmes résolus, mènera de véritables enquêtes pour comprendre ce que ressentent les développeurs, facilitera la soumission de bogues via des outils d'analyse et utilisera toutes ces données pour s'améliorer continuellement. Les développeurs doivent renforcer la confiance dans les outils d'analyse. Si un outil fait perdre du temps aux développeurs avec des faux positifs et des commentaires sur des problèmes de bas niveau, les développeurs perdront confiance et ignoreront les résultats.

Ne vous contentez pas de trouver des bugs, corrigez-les. Une approche typique pour promouvoir les outils d'analyse statique consiste à répertorier un grand nombre de problèmes dans la base de code. Le but est d'influencer l'action en signalant les erreurs potentielles à corriger ou d'éviter que des bugs ne se reproduisent à l'avenir. Mais si les développeurs ne sont pas incités à agir, ce résultat potentiellement souhaité restera lettre morte. Il s’agit d’un défaut fondamental : les outils d’analyse mesurent leur utilité par le nombre de problèmes qu’ils identifient, tandis que l’intégration des processus échoue avec seulement une poignée de corrections de bugs. Au contraire, l'équipe d'analyse statique de Google sera responsable des travaux de réparation correspondants ainsi que de la recherche de bugs, en utilisant cela comme critère de réussite d'une boucle fermée. En se concentrant sur la correction des erreurs, l'outil fournit des recommandations exploitables et minimise les faux positifs. Dans de nombreux cas, corriger les erreurs est aussi simple que de les trouver grâce à des outils automatisés. Même pour les problèmes difficiles à résoudre, les recherches menées au cours des cinq dernières années ont mis en évidence de nouvelles techniques permettant de créer automatiquement des correctifs pour les problèmes d'analyse statique.

Le développement d’analyseurs nécessite des efforts collectifs. Bien que des outils d'analyse statique spécifiques nécessitent que des développeurs experts rédigent l'analyse, peu d'experts savent réellement quelles vérifications produisent des facteurs d'impact plus importants. De plus, les experts en analyseurs ne sont souvent pas des experts du domaine (comme ceux travaillant avec les API, les langages et la sécurité). Intégration via FindBugs Seule une poignée d'employés de Google savaient comment écrire le nouveau vérificateur, la petite équipe de BugBot a donc dû faire tout le travail elle-même. Cela limite la vitesse à laquelle de nouveaux contrôles peuvent être ajoutés et empêche effectivement les autres de bénéficier de leurs contributions en matière de connaissances du domaine. Des équipes comme Tricorder s'efforcent désormais d'abaisser les normes relatives aux contrôles fournis par les développeurs, sans nécessiter d'expérience préalable en analyse statique. L'outil Google Refaster, par exemple, permet aux développeurs d'écrire des vérificateurs en spécifiant des exemples avant et après des extraits de code. Étant donné que les contributeurs sont souvent motivés à contribuer après avoir eux-mêmes débogué le code erroné, les nouvelles vérifications permettront aux développeurs de gagner du temps au fil du temps.

Conclusion

Notre expérience est que l'intégration dans le processus de développement est la clé de la mise en œuvre d'outils d'analyse statique. Bien que les auteurs d’outils de vérification puissent penser que les développeurs devraient être heureux d’être confrontés à des listes de défauts dans le code qu’ils écrivent, nous ne pensons pas que de telles listes motivent les développeurs à corriger ces défauts. En tant que développeurs d’outils d’analyse, nous devons définir l’efficacité des mesures en termes de défauts réellement corrigés, plutôt que de donner des chiffres aux développeurs. Cela signifie que nos responsabilités s’étendent bien au-delà des outils analytiques eux-mêmes.

Nous plaidons en faveur d'un système axé sur l'intégration des flux de travail le plus tôt possible. Activez le vérificateur en tant qu'erreur du compilateur autant que possible. Pour éviter que les rédacteurs d'outils de construction perturbateurs soient chargés de résoudre d'abord tous les problèmes existants dans la base de code, ce qui nous permet d'améliorer continuellement la qualité de la base de code de Google, étape par étape. Étant donné que nous présentons des avertissements d'erreur dans le compilateur, les développeurs les traitent immédiatement après avoir écrit le code afin qu'ils puissent toujours apporter des modifications en temps opportun. Pour y parvenir, nous avons développé l'infrastructure permettant d'exécuter des analyses et de générer des correctifs sur la vaste base de code de Google. Nous bénéficions également de révisions de code et d'automatisation des commits qui permettent de modifier des centaines de fichiers, et bien sûr d'une culture d'ingénierie qui tolère souvent l'incorporation de modifications dans le code existant, car l'amélioration du code l'emporte sur l'aversion au risque de modification.

La révision du code est le meilleur point d'entrée pour afficher les avertissements d'analyse avant de valider le code. Pour garantir que les développeurs acceptent les résultats de l'analyse, Tricorder affiche uniquement les problèmes pendant la phase de modification du code du développeur avant de valider la modification, et l'équipe Tricorder applique une série de critères pour sélectionner les alertes à afficher. Tricorder collecte en outre des statistiques dans l'outil de révision de code, qui est utilisé pour détecter la cause première de l'analyseur générant un grand nombre d'alertes non valides.

Afin de surmonter la négligence des alarmes, nous avons travaillé dur pour regagner la confiance des ingénieurs de Google et avons constaté que les développeurs de Google ont une forte tendance à ignorer l'analyse statique, et que tout rapport avec un taux de faux positifs insatisfaisant leur donne une raison de le faire. rien. L'équipe d'analyse est très prudente quant à l'affichage des résultats d'inspection sous forme d'erreurs ou d'avertissements uniquement après qu'ils ont été examinés par rapport à des critères objectifs descriptifs, de sorte que les développeurs sont rarement submergés, confus ou ennuyés par les résultats de l'analyse. Les enquêtes et les canaux de feedback sont des méthodes de contrôle qualité importantes pour ce processus. Maintenant que les développeurs ont repris confiance dans les résultats d'analyse, l'équipe Tricorder répond au besoin de davantage d'analyses pour être davantage impliquées dans les flux de travail des développeurs Google.

Nous avons construit une infrastructure d'analyse statique performante chez Google qui empêche chaque jour des centaines de bogues d'entrer dans la base de code de Google, à la fois au moment de la compilation et pendant la révision du code. Nous espérons que d’autres pourront bénéficier de notre expérience et intégrer avec succès l’analyse statique dans leurs propres flux de travail.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer