Analiza statyczna – od wprowadzenia do integracji

Zasady dotyczące niekończącego się przeglądu kodu lub debugowania sprawiają, że czasami zastanawiasz się, jak uprościć sobie życie. I trochę poszukując, albo przypadkiem natykając się, można natknąć się na magiczne hasło: "Analiza statyczna". Przyjrzyjmy się, czym to jest i jak może współdziałać z Twoim projektem.

Analiza statyczna – od wprowadzenia do integracji
Właściwie, jeśli piszesz w jakimkolwiek nowoczesnym języku, to nawet o tym nie wiedząc, przekazywałeś swój kod przez analizator statyczny. Chodzi o to, że każdy nowoczesny kompilator dostarcza, choćby w minimalnym stopniu, zestaw ostrzeżeń o potencjalnych problemach w kodzie. Na przykład, kompilując kod C++ w Visual Studio, możesz zobaczyć następujące:

Analiza statyczna – od wprowadzenia do integracji
W tym wyniku widzimy, że zmienna var nie została nigdzie użyta w funkcji. Tak więc w rzeczywistości prawie zawsze korzystałeś z prostego analizatora statycznego kodu. Jednak w przeciwieństwie do profesjonalnych analizatorów, takich jak Coverity, Klocwork czy PVS-Studio, ostrzeżenia dostarczane przez kompilator mogą wskazywać tylko na niewielki zakres problemów.

Jeśli nie wiesz na pewno, czym jest analiza statyczna i jak ją wprowadzać, przeczytaj ten artykuł, aby bardziej szczegółowo zapoznać się z tą metodologią.

Po co potrzebna jest analiza statyczna?

W skrócie: przyspieszenie i uproszczenie.

Analiza statyczna pozwala znaleźć wiele różnych problemów w kodzie: od niewłaściwego użycia konstrukcji języka po literówki. Na przykład, zamiast

auto x = obj.x;
auto y = obj.y;
auto z = obj.z;

napisałeś następujący kod:

auto x = obj.x;
auto y = obj.y;
auto z = obj.x;

Jak widzisz, w ostatniej linii pojawiła się literówka. Na przykład PVS-Studio zgłasza następujące ostrzeżenie:

V537 Rozważ sprawdzenie poprawności użycia elementu 'y'.

Jeśli chcesz samodzielnie zająć się tym błędem, spróbuj gotowego przykładu na Compiler Explorer: *klik*.

I jak rozumiesz, nie zawsze można zwrócić uwagę na takie fragmenty kodu od razu, a przez to można spędzić długie godziny na debugowaniu, zastanawiając się, dlaczego wszystko działa w taki dziwny sposób.

Jednak to oczywisty błąd. A co, jeśli programista napisał nieoptymalny kod, zapominając o jakiejś subtelności języka? Lub wręcz wprowadził do kodu nieokreślone zachowanie? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.

Dokładnie na takie sytuacje powstała analiza statyczna. To narzędzie dla programistów, które wskaże im różne problemy w kodzie i wyjaśni w dokumentacji, dlaczego nie należy pisać w ten sposób, do czego to może prowadzić i jak to naprawić. Oto przykład, jak to może wyglądać: *klik*.

Więcej interesujących błędów, które może wykryć analizator, znajdziesz w artykułach:

Teraz, po przeczytaniu tego materiału i upewnieniu się o korzyściach płynących z analizy statycznej, możesz chcieć wypróbować ją w praktyce. Ale od czego zacząć? Jak zintegrować nowe narzędzie w bieżącym projekcie? I jak zapoznać z nim zespół? Odpowiedzi na te pytania znajdziesz poniżej.

Uwaga. Analiza statyczna nie zastępuje i nie znosi tak przydatnej rzeczy, jak przeglądy kodu. Uzupełnia ten proces, pomagając wcześniej zauważyć i naprawić literówki, niedokładności i niebezpieczne konstrukcje. znacznie bardziej produktywne jest skoncentrowanie się podczas przeglądów kodu na algorytmach i czytelności kodu, a nie na wyłapywaniu źle umieszczonych nawiasów czy czytaniu nudnych funkcji porównawczych.

0. Wprowadzenie do narzędzia

Wszystko zaczyna się od wersji próbnej. Rzeczywiście, trudno zdecydować się na wdrożenie czegokolwiek w procesie rozwijania, jeśli nigdy wcześniej nie widziało się narzędzia na żywo. Dlatego najpierw warto pobrać wersję próbną.

Co dowiesz się na tym etapie:

  • Jakie są sposoby interakcji z analizatorem;
  • Czy analizator jest kompatybilny z Twoim środowiskiem programistycznym;
  • Jakie problemy występują obecnie w Twoich projektach.

Po zainstalowaniu wszystkich niezbędnych elementów, pierwszym krokiem powinno być uruchomienie analizy całego projektu (Windows, Linuxa, macOS). W przypadku PVS-Studio w Visual Studio zobaczysz podobny widok (klikalnie):

Analiza statyczna – od wprowadzenia do integracji
Faktem jest, że zazwyczaj na projektach z dużą bazą kodu analizatory statyczne generują ogromną liczbę ostrzeżeń. Nie ma potrzeby naprawiania ich wszystkich, ponieważ Twój projekt już działa, a zatem te problemy nie są krytyczne. Jednak możesz rzucić okiem na najbardziej interesujące ostrzeżenia i w razie potrzeby je poprawić. W tym celu należy przefiltrować wyniki, pozostawiając tylko najbardziej wiarygodne komunikaty. Wtyczka PVS-Studio dla Visual Studio umożliwia to poprzez filtrowanie według poziomów i kategorii błędów. Aby uzyskać najbardziej precyzyjny wynik, należy pozostawić włączone tylko Wysoki i General (także klikalne):

Analiza statyczna – od wprowadzenia do integracji
Rzeczywiście, przeglądanie 178 ostrzeżeń jest znacznie łatwiejsze niż kilku tysięcy...

W zakładkach Medium i Niski często trafiają się dobre ostrzeżenia, jednak do tych kategorii zalicza się również diagnozy, które mają mniejszą precyzję (wiarygodność). Więcej na temat poziomów ostrzeżeń i możliwości pracy w systemie Windows można zobaczyć tutaj: *klik*.

Po pomyślnym przejrzeniu najciekawszych błędów (i ich poprawieniu) warto stłumić pozostałe ostrzeżenia. Jest to konieczne, aby nowe ostrzeżenia nie ginęły wśród starych. Poza tym, analizator statyczny to pomocnik dla programisty, a nie lista błędów. 🙂

1. Automatyzacja

Po zapoznaniu się przychodzi czas na konfigurację wtyczek i integrację w CI. Należy to zrobić, zanim programiści zaczną korzystać z analizatora statycznego. Chodzi o to, że programista może zapomnieć włączyć analizę lub w ogóle jej nie chcieć. W tym celu trzeba przeprowadzić pewną końcową kontrolę wszystkiego, aby niezweryfikowany kod nie trafił do ogólnej gałęzi rozwoju.

Czego dowiesz się na tym etapie:

  • Jakie opcje automatyzacji oferuje narzędzie;
  • Czy analizator jest kompatybilny z twoim systemem budowania.

Ponieważ nie ma idealnej dokumentacji, czasami trzeba pisać do wsparcie. To normalne, i cieszymy się, mogąc pomóc. 🙂

A teraz przejdźmy do usług ciągłej integracji (CI). Każdy analizator można w nie wdrożyć bez większych problemów. W tym celu należy stworzyć oddzielny etap w pipeline, który zwykle znajduje się po budowie i testach jednostkowych. Wykonuje się to przy pomocy różnych narzędzi konsolowych. Na przykład PVS-Studio oferuje następujące narzędzia:

Aby zintegrować analizę w CI, należy wykonać trzy rzeczy:

  • Zainstalować analizator;
  • Uruchom analizę;
  • Dostarcz wyniki.

Na przykład, aby zainstalować PVS-Studio na Linuxie (oparty na Debianie), należy wykonać następujące komendy:

wget -q -O - https://files.viva64.com/etc/pubkey.txt 
    | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list 
  https://files.viva64.com/etc/viva64.list
  
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio

W systemach opartych na Windows nie ma możliwości zainstalowania analizatora z menedżera pakietów, jednak istnieje możliwość uruchomienia analizatora z linii poleceń:

PVS-Studio_setup.exe /verysilent /suppressmsgboxes 
/norestart /nocloseapplications

Więcej o wdrażaniu PVS-Studio w systemach opartych na Windows można przeczytać *tutaj*.

Po zainstalowaniu należy uruchomić bezpośrednio analizę. Zaleca się to robić dopiero po zakończeniu kompilacji i testów. Wynika to z faktu, że do analizy statycznej zwykle potrzeba dwa razy więcej czasu niż do kompilacji.

Ponieważ sposób uruchamiania zależy od platformy i specyfiki projektu, pokażę przykład dla C++ (Linux):

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w

Pierwsza komenda wykona analizę, a druga konwertujeraport do formatu tekstowego, wyświetli go na ekranie i zwróci kod wyjścia różny od 0 w przypadku wystąpienia ostrzeżeń. Taki mechanizm jest wygodny do blokowania kompilacji w przypadku wystąpienia komunikatów o błędach. Można jednak zawsze usunąć flagę -w i nie blokować kompilacji zawierającej ostrzeżenia.

Uwaga. Format tekstowy — to niewygodne. Podano go tylko jako przykład. Zwróć uwagę na bardziej interesujący format raportu — FullHtml. Umożliwia on nawigację po kodzie.

Więcej o konfiguracji analizy w CI można przeczytać w artykule "PVS-Studio i Continuous Integration" (Windows) lub "Jak skonfigurować PVS-Studio w Travis CI" (Linux).

Dobrze, skonfigurowałeś działanie analizatora na serwerze budowlanym. Teraz, jeżeli ktoś załadował niezweryfikowany kod, etap weryfikacji się nie powiedzie, i będziesz mógł wykryć problem, jednak to nie jest zbyt wygodne, ponieważ efektywniej jest sprawdzać projekt nie po tym, jak nastąpiło scalanie gałęzi, a przed, na etapie pull requesta.

Ogólnie, konfiguracja analizy pull requesta niewiele różni się od zwykłego uruchamiania analizy w CI. Z wyjątkiem konieczności uzyskania listy zmienionych plików. Zazwyczaj można je uzyskać, żądając różnicy między gałęziami za pomocą git:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

Teraz trzeba przekazać ten wykaz plików do analizatora. Na przykład, w PVS-Studio można to zrealizować za pomocą flagi -S:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Więcej informacji na temat analizy pull requestów można znaleźć *tutaj*. Nawet jeśli nie masz swojego CI na liście wskazanych w artykule usług, przydatny będzie ogólny rozdział poświęcony teorii tego rodzaju analizy.

Konfigurując analizę pull requestów, możesz zablokować commity zawierające ostrzeżenia, tworząc w ten sposób granicę, której nieprzetworzony kod nie będzie mógł przekroczyć.

To wszystko jest oczywiście bardzo dobre, jednak chciałbym mieć możliwość przeglądania wszystkich ostrzeżeń w jednym miejscu. Nie tylko od analizatora statycznego, ale także od testów jednostkowych czy od analizatora dynamicznego. W tym celu istnieją różne usługi i wtyczki. PVS-Studio, na przykład, ma wtyczkę do integracji z SonarQube.

2. Integracja na maszynach programistów

Teraz nadszedł czas na instalację i konfigurację analizatora do codziennego użytku podczas programowania. Do tego momentu zaznajomiłeś się z większością metod pracy, więc można to nazwać najłatwiejszą częścią.

Najprostsza opcja – programiści mogą sami zainstalować potrzebny analizator. Jednak zajmie to dużo czasu i odciągnie ich od programowania, dlatego możesz zautomatyzować ten proces, używając instalatora i odpowiednich flag. Dla PVS-Studio istnieje wiele flag dla zautomatyzowanej instalacji. Zresztą, zawsze są menedżery pakietów, takie jak Chocolatey (Windows), Homebrew (macOS) lub dziesiątki opcji dla Linuxa.

Następnie trzeba będzie zainstalować wymagane wtyczki, na przykład do Visual Studio, IDEA, Rider etc.

3. Codzienne użytkowanie

Na tym etapie warto powiedzieć kilka słów o sposobach przyspieszenia pracy analizatora w codziennym użytkowaniu. Pełna analiza całego projektu zajmuje bardzo dużo czasu, jednak czy często zmieniamy kod jednocześnie w całym projekcie? Niewątpliwie opracowanie tak dużego refaktoringu, który natychmiast dotknie całej bazy kodu, jest rzadkie. Liczba zmienianych plików naraz rzadko przekracza dziesięć, dlatego warto je analizować. Dla takiej sytuacji istnieje tryb analizy inkrementalnejTylko się nie przestrasz, to nie kolejne narzędzie. To specjalny tryb, który pozwala analizować tylko zmienione pliki i ich zależności, a wszystko to dzieje się automatycznie po kompilacji, jeśli pracujesz w IDE z zainstalowanym wtyczką.

Jeśli analizator wykryje problemy w niedawno zmienionym kodzie, sam o tym poinformuje. Na przykład, PVS-Studio powiadomi cię o tym za pomocą powiadomienia:

Analiza statyczna – od wprowadzenia do integracji
Oczywiście, to za mało, by powiedzieć programistom, aby używali narzędzia. Musisz jakoś im opowiedzieć, co to jest i jak to działa. Oto na przykład artykuły dotyczące szybkiego startu w PVS-Studio, ale podobne poradniki znajdziesz dla każdego preferowanego przez siebie narzędzia:

Podobne artykuły dostarczają wszystkie niezbędne informacje do codziennego użytku i nie zajmują dużo czasu. 🙂

Już na etapie zaznajamiania się z narzędziem zredukowaliśmy wiele ostrzeżeń podczas jednego z pierwszych uruchomień. Niestety, statyczne analizatory nie są idealne, dlatego od czasu do czasu generują fałszywe alarmy. Zwykle można je łatwo stłumić, na przykład w wtyczce PVS-Studio dla Visual Studio wystarczy nacisnąć jeden przycisk:

Analiza statyczna – od wprowadzenia do integracji
Jednak możesz nie tylko je stłumić. Na przykład, możesz zgłosić do wsparcia istnienie problemu. Jeśli fałszywy alarm można naprawić, to w przyszłych aktualizacjach możesz zauważyć, że z każdym razem jest coraz mniej specyficznych dla twojej bazy kodu fałszywych alarmów.

Po integracji

Oto przeszliśmy przez wszystkie etapy integracji analizy statycznej w procesie rozwoju. Mimo że konfiguracja takich narzędzi w CI jest ważna, najważniejszym miejscem uruchomienia jest właśnie komputer programisty. Przecież statyczny analizator to nie sędzia, który mówi z daleka, że kod się nie nadaje. Wręcz przeciwnie, to pomocnik, który podpowiada, gdy jesteś zmęczony i przypomina, jeśli o czymś zapomniałeś.

Prawda jest taka, że bez regularnego korzystania statyczna analiza raczej nie uprości znacznie procesu tworzenia oprogramowania. W końcu jej główną zaletą dla programisty jest nie tyle wyszukiwanie skomplikowanych i kontrowersyjnych fragmentów kodu, ile wczesne ich wykrywanie. Zgódź się, że odkrycie problemu, gdy poprawki są już w fazie testów, jest nie tylko nieprzyjemne, ale również bardzo czasochłonne. Statyczna analiza, przy regularnym używaniu, przegląda każdą zmianę bezpośrednio na twoim komputerze i informuje o podejrzanych miejscach w trakcie pracy nad kodem.

A jeśli ty lub twoi koledzy nadal nie jesteście pewni, czy warto wprowadzać analizator, proponuję teraz przejść do lektury artykułu "Powody, dla których warto wdrożyć do procesu tworzenia statyczny analizator kodu PVS-Studio". W nim omówione zostały typowe obawy programistów, że statyczna analiza pochłonie ich czas itp.

Analiza statyczna – od wprowadzenia do integracji

Jeśli chcesz podzielić się tym artykułem z anglojęzyczną publicznością, proszę użyj linku do tłumaczenia: Maxim Zvyagintsev. Static Analysis: From Getting Started to Integration.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster