Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu

Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu
Je snadné vyzkoušet analyzátor statického kódu. Ale implementovat to, zejména při vývoji velkého starého projektu, vyžaduje dovednost. Pokud se to udělá špatně, může analyzátor přidat práci, zpomalit vývoj a demotivovat tým. Pojďme si krátce říci, jak správně přistoupit k integraci statické analýzy do procesu vývoje a začít ji používat jako součást CI/CD.

úvod

Nedávno mě zaujala publikace „Začínáme se statickou analýzou bez přetížení týmu". Na jednu stranu je to dobrý článek, se kterým stojí za to se seznámit. Na druhou stranu se mi zdá, že stále nedává úplnou odpověď na to, jak bezbolestně implementovat statický rozbor v projektu s hodně Článek říká, že můžete přijmout technický dluh a pracovat pouze na novém kódu, ale neexistuje odpověď na to, co s tímto technickým dluhem dělat později.

Náš tým PVS-Studio nabízí svůj pohled na toto téma. Podívejme se, jak vůbec problém implementace analyzátoru statického kódu vzniká, jak tento problém překonat a jak bezbolestně postupně odstranit technický dluh.

Problémy

Obvykle není obtížné spustit a zjistit, jak funguje statický analyzátor [1]. V kódu můžete vidět zajímavé chyby nebo dokonce děsivé potenciální zranitelnosti. Můžete i něco opravit, ale pak to mnoho programátorů vzdá.

Všechny statické analyzátory produkují falešně pozitivní výsledky. Toto je vlastnost metodologie analýzy statického kódu a nelze s tím nic dělat. V obecném případě se jedná o neřešitelný problém, jak potvrzuje Riceův teorém [2]. Nepomohou ani algoritmy strojového učení [3]. I když člověk nemůže vždy říct, zda je ten či onen kód špatný, neměli byste to od programu očekávat :).

Falešné poplachy nepředstavují problém, pokud je statický analyzátor již nakonfigurován:

  • Zakázat irelevantní sady pravidel;
  • Některé nepodstatné diagnostiky byly zakázány;
  • Pokud mluvíme o C nebo C++, pak jsou označena makra, která obsahují specifické konstrukce, které způsobují zbytečná varování na každém místě, kde se taková makra používají;
  • Jsou označeny vlastní funkce, které provádějí činnosti podobné funkcím systému (jeho vlastní analog memcpy nebo printf) [4];
  • Falešné poplachy jsou specificky zakázány pomocí komentářů;
  • A tak dále.

V tomto případě můžeme očekávat nízkou míru falešné pozitivity kolem 10-15 % [5]. Jinými slovy, 9 z 10 varování analyzátoru bude indikovat skutečný problém v kódu, nebo alespoň „silně páchnoucí kód“. Souhlasíte, tento scénář je velmi příjemný a analyzátor je skutečný přítel programátora.

Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu
Ve skutečnosti ve velkém projektu bude počáteční obrázek úplně jiný. Analyzátor vydává stovky nebo tisíce varování pro starší kód. Není možné rychle pochopit, která z těchto varování jsou relevantní a která ne. Je iracionální si sednout a začít se všemi těmito varováními zabývat, protože hlavní práce se v tomto případě zastaví na dny nebo týdny. Takový scénář si tým obvykle nemůže dovolit. Bude také velké množství rozdílů, které kazí historii změn. A rychlá hromadná úprava tolika fragmentů v kódu nevyhnutelně povede k novým překlepům a chybám.

A co je nejdůležitější, takový počin v boji proti varováním nedává smysl. Souhlasíte s tím, že protože projekt úspěšně běží mnoho let, většina kritických chyb v něm již byla opravena. Ano, tyto opravy byly velmi drahé, musely být odladěny, dostávaly negativní zpětnou vazbu od uživatelů ohledně chyb a tak dále. Statický analyzátor by pomohl opravit mnoho z těchto chyb ve fázi kódování, rychle a levně. Ale v tuto chvíli, tak či onak, byly tyto chyby opraveny a analyzátor detekuje hlavně nekritické chyby ve starém kódu. Tento kód se nesmí používat, může se používat velmi zřídka a chyba v něm nemusí mít znatelné následky. Možná je někde stín z tlačítka nesprávná barva, ale to nikomu nebrání v používání produktu.

Samozřejmě i drobné chyby jsou stále chybami. A někdy chyba může skrývat skutečnou zranitelnost. Ovšem vzdát se všeho a trávit dny/týdny řešením závad, které se sotva projevují, vypadá jako pochybný nápad.

Programátoři se dívají, dívají, prohlížejí všechna tato varování o starém funkčním kódu... A myslí si: obejdeme se bez statické analýzy. Pojďme napsat nějaké nové užitečné funkce.

Svým způsobem mají pravdu. Uvědomují si, že se nejprve musí nějak zbavit všech těchto varování. Jen tak budou moci těžit z pravidelného používání analyzátoru kódu. Jinak se nová varování jednoduše utopí ve starých a nikdo jim nebude věnovat pozornost.

Je to stejná analogie jako u varování kompilátoru. Ne nadarmo doporučují udržovat počet varování kompilátoru na 0. Pokud je varování 1000, pak když jich je 1001, nikdo tomu nebude věnovat pozornost a není jasné, kde toto nejnovější varování hledat.

Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu
Nejhorší na tomto příběhu je, když vás v tuto chvíli někdo shora donutí použít statickou analýzu kódu. Tým to pouze demotivuje, protože z jejich pohledu to bude další byrokratická složitost, která jen překáží. Nikdo se nebude dívat na zprávy analyzátoru a veškeré použití bude pouze „na papíře“. Tito. Formálně je analýza zabudována do procesu DevOps, ale v praxi to nikomu neprospívá. Slyšeli jsme podrobné příběhy na stáncích od účastníků konference. Taková zkušenost může odradit programátory od používání nástrojů statické analýzy na dlouhou dobu, ne-li navždy.

Zavedení a odstranění technického dluhu

Ve skutečnosti není nic těžkého nebo děsivého na zavedení statické analýzy i do velkého starého projektu.

CI / CD

Analyzátor se navíc může okamžitě stát součástí procesu neustálého vývoje. Například distribuce PVS-Studio obsahuje nástroje pro pohodlné prohlížení sestavy ve formátu, který potřebujete, a upozornění pro vývojáře, kteří napsali problematické části kódu. Těm, kteří se více zajímají o spuštění PVS-Studio z CI/CD systémů, doporučuji seznámit se s příslušným sekce dokumentace a série článků:

Ale vraťme se k problému velkého počtu falešných poplachů v prvních fázích implementace nástrojů pro analýzu kódu.

Oprava stávajícího technického dluhu a řešení nových varování

Moderní komerční statické analyzátory umožňují studovat pouze nová varování, která se objevují v novém nebo změněném kódu. Implementace tohoto mechanismu se liší, ale podstata je stejná. Ve statickém analyzátoru PVS-Studio je tato funkce implementována následovně.

Chcete-li rychle začít používat statickou analýzu, doporučujeme uživatelům PVS-Studio použít mechanismus pro hromadné potlačení varování [6]. Obecná myšlenka je následující. Uživatel spustil analyzátor a obdržel mnoho varování. Vzhledem k tomu, že projekt, který byl vyvíjen mnoho let, je živý, vyvíjí se a vydělává peníze, s největší pravděpodobností nebude ve zprávě mnoho varování označujících kritické závady. Jinými slovy, kritické chyby již byly tak či onak opraveny pomocí dražších metod nebo díky zpětné vazbě od zákazníků. V souladu s tím lze vše, co analyzátor aktuálně najde, považovat za technický dluh, který je nepraktické snažit se okamžitě odstranit.

Můžete říct PVS-Studio, aby tato varování prozatím považovala za irelevantní (technický dluh si ponechal na později) a už je nebude zobrazovat. Analyzátor vytvoří speciální soubor, kam ukládá informace o chybách, které zatím nejsou zajímavé. A nyní bude PVS-Studio vydávat varování pouze pro nový nebo změněný kód. To vše je navíc chytře implementováno. Pokud je například na začátek souboru zdrojového kódu přidán prázdný řádek, pak analyzátor pochopí, že se ve skutečnosti nic nezměnilo, a bude nadále mlčet. Tento soubor značek lze vložit do systému správy verzí. Soubor je velký, ale to není problém, protože nemá smysl ho často ukládat.

Nyní všichni programátoři uvidí varování týkající se pouze nového nebo změněného kódu. Analyzátor tedy můžete začít používat, jak se říká, od dalšího dne. A později se můžete vrátit k technickému dluhu a postupně opravovat chyby a konfigurovat analyzátor.

První problém s implementací analyzátoru ve velkém starém projektu byl tedy vyřešen. Nyní pojďme zjistit, co dělat s technickým dluhem.

Opravy chyb a refaktoringy

Nejjednodušší a nejpřirozenější je vyhradit si čas na analýzu masivně potlačovaných varování analyzátoru a postupně se s nimi vypořádat. Někde byste měli opravit chyby v kódu, někde byste měli refaktorovat, abyste analyzátoru řekli, že kód není problematický. Jednoduchý příklad:

if (a = b)

Většina kompilátorů a analyzátorů C++ si na takový kód stěžuje, protože existuje vysoká pravděpodobnost, že skutečně chtěli napsat (a == b). Existuje však nevyslovená shoda, a to je obvykle uvedeno v dokumentaci, že pokud existují další závorky, má se za to, že programátor napsal takový kód úmyslně, a není třeba nadávat. Například v dokumentaci PVS-Studio pro diagnostiku V559 (CWE-481) je jasně napsáno, že následující řádek bude považován za správný a bezpečný:

if ((a = b))

Další příklad. Je to zapomenuto v tomto kódu C++? rozbít nebo ne?

case A:
  foo();
case B:
  bar();
  break;

Analyzátor PVS-Studio zde vydá varování V796 (CWE-484). Nemusí se jednat o chybu, v takovém případě byste měli analyzátoru napovědět přidáním atributu [[propadnout]] nebo například __attribute__((fallthrough)):

case A:
  foo();
  [[fallthrough]];
case B:
  bar();
  break;

Dá se říci, že takové změny kódu chybu neopravují. Ano, to je pravda, ale přináší to dvě užitečné věci. Za prvé, zpráva analyzátoru se zbaví falešných poplachů. Za druhé, kód se stává srozumitelnějším pro lidi, kteří se podílejí na jeho údržbě. A to je velmi důležité! Už jen kvůli tomu stojí za to provést menší refaktoringy, aby byl kód jasnější a snadnější na údržbu. Vzhledem k tomu, že analyzátor nerozumí tomu, zda je potřeba „break“ nebo ne, nebude to jasné ani ostatním programátorům.

Kromě oprav chyb a refaktoringů můžete specificky potlačit zjevně falešná varování analyzátoru. Některé nepodstatné diagnostiky lze zakázat. Někdo si například myslí, že varování jsou zbytečná V550 o porovnání hodnot float/double. A někteří je klasifikují jako důležité a hodné studia [7]. Která varování jsou považována za relevantní a která ne, je na rozhodnutí vývojového týmu.

Existují další způsoby, jak potlačit falešná upozornění. Například makro značkování bylo zmíněno dříve. To vše je podrobněji popsáno v dokumentaci. Nejdůležitější je pochopit, že pokud postupně a systematicky přistupujete k práci s falešnými pozitivy, není na nich nic špatného. Naprostá většina nezajímavých varování po konfiguraci zmizí a zůstanou jen místa, která opravdu vyžadují pečlivé studium a nějaké změny v kódu.

Také vždy pomáháme našim klientům nastavit PVS-Studio, pokud se vyskytnou nějaké potíže. Navíc se vyskytly případy, kdy jsme sami odstranili falešná varování a opravili chyby [8]. Pro každý případ jsem se rozhodl zmínit, že je možná i tato možnost rozšířené spolupráce :).

Ratchetova metoda

Existuje další zajímavý přístup k postupnému zlepšování kvality kódu odstraněním varování statického analyzátoru. Pointa je, že počet varování se může pouze snižovat.

Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu

Zaznamenává se počet varování vydaných statickým analyzátorem. Brána kvality je nakonfigurována tak, že nyní můžete zadat pouze kód, který nezvyšuje počet operací. Výsledkem je, že proces postupného snižování počtu alarmů začíná nastavením analyzátoru a opravou chyb.

I když chce člověk trochu podvádět a rozhodne se projít bránou kvality nikoli odstraněním varování ve svém novém kódu, ale vylepšením starého kódu třetích stran, není to děsivé. Přesto se ráčna otáčí jedním směrem a postupně se bude počet defektů snižovat. I když si člověk nechce opravovat své vlastní nové vady, stejně bude muset něco vylepšit v sousedním kódu. V určitém okamžiku jednoduché způsoby, jak snížit počet varování, končí a přichází bod, kdy budou opraveny skutečné chyby.

Tato metodika je podrobněji popsána ve velmi zajímavém článku Ivana Ponomareva "Implementujte do procesu statickou analýzu místo toho, abyste ji používali k hledání chyb“, kterou doporučuji přečíst každému, kdo má zájem zlepšit kvalitu kódu.

Autor článku má na toto téma také zprávu: "Průběžná statická analýza".

Závěr

Doufám, že po tomto článku budou čtenáři nástroje statické analýzy více akceptovat a budou je chtít implementovat do procesu vývoje. Pokud máte nějaké dotazy, jsme vždy připraveni poradit uživatelům našeho statického analyzátoru PVS-Studio a pomoc s jeho implementací.

Existují další typické pochybnosti o tom, zda může být statická analýza skutečně pohodlná a užitečná. Většinu těchto pochybností jsem se pokusil rozptýlit v publikaci „Důvody zavedení analyzátoru statického kódu PVS-Studio do procesu vývoje“ [9].

Děkuji za pozornost a přijďte ke stažení a vyzkoušejte analyzátor PVS-Studio.

Další odkazy

  1. Andrej Karpov. Jak mohu rychle vidět zajímavá varování, která analyzátor PVS-Studio vytváří pro kód C a C++?
  2. Wikipedia. Riceova věta.
  3. Andrey Karpov, Victoria Khanieva. Využití strojového učení při statické analýze zdrojového kódu programu.
  4. PVS-Studio. Dokumentace. Další diagnostická nastavení.
  5. Andrej Karpov. Charakteristika analyzátoru PVS-Studio na příkladu EFL Core Libraries, 10-15 % falešně pozitivních výsledků.
  6. PVS-Studio. Dokumentace. Hromadné potlačení zpráv analyzátoru.
  7. Ivan Andryashin. O tom, jak jsme testovali statickou analýzu na našem projektu výukového simulátoru RTG endovaskulární chirurgie.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Jak tým PVS-Studio vylepšil kód Unreal Engine.
  9. Andrej Karpov. Důvody pro zavedení statického analyzátoru kódu PVS-Studio do procesu vývoje.

Jak implementovat analyzátor statického kódu do staršího projektu bez demotivace týmu

Pokud chcete tento článek sdílet s anglicky mluvícím publikem, použijte odkaz na překlad: Andrey Karpov. Jak zavést statický analyzátor kódu ve starším projektu a neodradit tým.

Zdroj: www.habr.com

Přidat komentář