Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin

Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin
Është e lehtë të provosh një analizues të kodit statik. Por për ta zbatuar atë, veçanërisht në zhvillimin e një projekti të madh të vjetër, kërkon aftësi. Nëse bëhet gabimisht, analizuesi mund të shtojë punë, të ngadalësojë zhvillimin dhe të demotivojë ekipin. Le të flasim shkurtimisht se si t'i qasemi siç duhet integrimit të analizës statike në procesin e zhvillimit dhe të fillojmë ta përdorim atë si pjesë e CI/CD.

Paraqitje

Kohët e fundit vëmendja ime u tërhoq nga botimi "Fillimi me analizën statike pa e mbingarkuar ekipin". Nga njëra anë, ky është një artikull i mirë që ia vlen të njiheni. Nga ana tjetër, më duket se ende nuk jep një përgjigje të plotë se si të zbatohet pa dhimbje analiza statike në një projekt me shumë i kodit të trashëguar Artikulli thotë se ju mund të pranoni borxhin teknik dhe të punoni vetëm me kodin e ri, por nuk ka përgjigje se çfarë të bëni me këtë borxh teknik më vonë.

Ekipi ynë i PVS-Studio ofron pikëpamjen e tij mbi këtë temë. Le të shohim se si lind në radhë të parë problemi i zbatimit të një analizuesi të kodit statik, si ta kapërcejmë këtë problem dhe si të eliminojmë gradualisht borxhin teknik pa dhimbje.

Çështjet

Zakonisht nuk është e vështirë të nisësh dhe të shohësh se si funksionon një analizues statik [1]. Mund të shihni gabime interesante apo edhe dobësi të mundshme të frikshme në kod. Madje mund të rregulloni diçka, por më pas shumë programues heqin dorë.

Të gjithë analizuesit statikë prodhojnë rezultate false. Kjo është një veçori e metodologjisë së analizës së kodit statik dhe nuk mund të bëhet asgjë për të. Në rastin e përgjithshëm, ky është një problem i pazgjidhshëm, siç konfirmohet nga teorema e Rice [2]. Algoritmet e mësimit të makinerisë nuk do të ndihmojnë as [3]. Edhe nëse një person nuk mund të tregojë gjithmonë nëse ky apo ai kod është i gabuar, atëherë nuk duhet ta prisni këtë nga programi :).

Pozitivet e rreme nuk janë problem nëse analizuesi statik është tashmë i konfiguruar:

  • Paaktivizuar grupe rregullash të parëndësishme;
  • Disa diagnostifikime të parëndësishme janë çaktivizuar;
  • Nëse po flasim për C ose C++, atëherë shënohen makro që përmbajnë konstruksione specifike që shkaktojnë paralajmërime të padobishme të shfaqen në çdo vend ku përdoren makro të tilla;
  • Shënohen funksionet e veta që kryejnë veprime të ngjashme me funksionet e sistemit (analogu i vet memecpy ose printf) [4];
  • Pozitivet e rreme çaktivizohen në mënyrë specifike duke përdorur komentet;
  • Dhe kështu me radhë.

Në këtë rast, mund të presim një normë të ulët false pozitive prej rreth 10-15% [5]. Me fjalë të tjera, 9 nga 10 paralajmërimet e analizuesit do të tregojnë një problem real në kod, ose të paktën "kod me erë të fortë". Pajtohem, ky skenar është jashtëzakonisht i këndshëm, dhe analizuesi është një mik i vërtetë i programuesit.

Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin
Në realitet, në një projekt të madh, fotografia fillestare do të jetë krejtësisht e ndryshme. Analizuesi lëshon qindra ose mijëra paralajmërime për kodin e vjetër. Është e pamundur të kuptosh shpejt se cilat nga këto paralajmërime janë relevante dhe cilat jo. Është e paarsyeshme të ulesh dhe të fillosh të merresh me të gjitha këto paralajmërime, pasi puna kryesore në këtë rast do të ndalet për ditë ose javë. Në mënyrë tipike, një ekip nuk mund të përballojë një skenar të tillë. Do të ketë gjithashtu një numër të madh ndryshimesh që prishin historinë e ndryshimeve. Dhe redaktimi i shpejtë masiv i kaq shumë fragmenteve në kod do të rezultojë në mënyrë të pashmangshme në gabime të reja shtypi dhe gabime.

Dhe më e rëndësishmja, një sukses i tillë në luftën kundër paralajmërimeve ka pak kuptim. Pajtohem që meqenëse projekti ka funksionuar me sukses për shumë vite, shumica e gabimeve kritike në të tashmë janë korrigjuar. Po, këto rregullime ishin shumë të shtrenjta, duhej të korrigjoheshin, merrnin komente negative nga përdoruesit për defektet, etj. Një analizues statik do të ndihmonte në rregullimin e shumë prej këtyre gabimeve në fazën e kodimit, shpejt dhe me çmim të ulët. Por për momentin, në një mënyrë ose në një tjetër, këto gabime janë rregulluar dhe analizuesi kryesisht zbulon gabime jo kritike në kodin e vjetër. Ky kod mund të mos përdoret, mund të përdoret shumë rrallë dhe një gabim në të mund të mos çojë në pasoja të dukshme. Ndoshta diku hija nga butoni është ngjyra e gabuar, por kjo nuk ndërhyn në përdorimin e produktit nga askush.

Sigurisht, edhe gabimet e vogla janë ende gabime. Dhe ndonjëherë një gabim mund të fshehë një dobësi të vërtetë. Megjithatë, të heqësh dorë nga gjithçka dhe të kalosh ditë/javë duke u marrë me defekte që mezi manifestohen duket si një ide e dyshimtë.

Programuesit shikojnë, shikojnë, shikojnë të gjitha këto paralajmërime për kodin e vjetër të punës... Dhe ata mendojnë: ne mund të bëjmë pa analiza statike. Le të shkojmë të shkruajmë disa funksione të reja të dobishme.

Në mënyrën e tyre, ata kanë të drejtë. Ata kuptojnë se së pari duhet të heqin qafe të gjitha këto paralajmërime. Vetëm atëherë ata do të jenë në gjendje të përfitojnë nga përdorimi i rregullt i analizuesit të kodit. Përndryshe, paralajmërimet e reja thjesht do të mbyten në të vjetrat dhe askush nuk do t'u kushtojë vëmendje atyre.

Kjo është e njëjta analogji si me paralajmërimet e përpiluesit. Jo pa arsye rekomandojnë mbajtjen e numrit të paralajmërimeve të përpiluesit në 0. Nëse janë 1000 paralajmërime, atëherë kur janë 1001, askush nuk do t'i kushtojë vëmendje dhe nuk është e qartë se ku duhet kërkuar këtë paralajmërim më të ri.

Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin
Gjëja më e keqe në këtë histori është nëse dikush nga lart në këtë moment ju detyron të përdorni analizën statike të kodit. Kjo vetëm sa do të demotivojë ekipin, pasi nga këndvështrimi i tyre do të ketë një kompleksitet shtesë burokratik që vetëm sa pengon. Askush nuk do të shikojë raportet e analizuesit dhe i gjithë përdorimi do të jetë vetëm "në letër". Ato. Formalisht, analiza është e integruar në procesin DevOps, por në praktikë kjo nuk i sjell dobi askujt. Ne dëgjuam histori të detajuara në kabinat nga pjesëmarrësit e konferencës. Një përvojë e tillë mund t'i dekurajojë programuesit nga përdorimi i mjeteve të analizës statike për një kohë të gjatë, nëse jo përgjithmonë.

Zbatimi dhe eliminimi i borxhit teknik

Në fakt, nuk ka asgjë të vështirë apo të frikshme për futjen e analizave statike edhe në një projekt të madh të vjetër.

CI / CD

Për më tepër, analizuesi mund të bëhet menjëherë pjesë e procesit të zhvillimit të vazhdueshëm. Për shembull, shpërndarja PVS-Studio përmban mjete për të parë me lehtësi raportin në formatin që ju nevojitet, dhe njoftime për zhvilluesit që kanë shkruar seksione problematike të kodit. Për ata që janë më të interesuar të lançojnë PVS-Studio nga sistemet CI/CD, ju rekomandoj që të njiheni me ato përkatëse. seksioni dokumentacion dhe një seri artikujsh:

Por le të kthehemi te çështja e një numri të madh të provave false në fazat e para të zbatimit të mjeteve të analizës së kodit.

Rregullimi i borxhit teknik ekzistues dhe trajtimi i paralajmërimeve të reja

Analizuesit statikë komercialë modernë ju lejojnë të studioni vetëm paralajmërimet e reja që shfaqen në kodin e ri ose të ndryshuar. Zbatimi i këtij mekanizmi ndryshon, por thelbi është i njëjtë. Në analizuesin statik PVS-Studio, ky funksionalitet zbatohet si më poshtë.

Për të filluar me shpejtësi përdorimin e analizës statike, ne sugjerojmë përdoruesit e PVS-Studio të përdorin mekanizmin për shtypjen masive të paralajmërimeve [6]. Ideja e përgjithshme është si më poshtë. Përdoruesi nisi analizuesin dhe mori shumë paralajmërime. Meqenëse një projekt që ka qenë në zhvillim për shumë vite është i gjallë, në zhvillim dhe duke fituar para, atëherë me shumë mundësi nuk do të ketë shumë paralajmërime në raport që tregojnë defekte kritike. Me fjalë të tjera, gabimet kritike tashmë janë rregulluar në një mënyrë ose në një tjetër duke përdorur metoda më të shtrenjta ose falë reagimeve nga klientët. Prandaj, gjithçka që analizuesi gjen aktualisht mund të konsiderohet borxh teknik, i cili nuk është praktik të përpiqet të eliminohet menjëherë.

Ju mund t'i thoni PVS-Studio që t'i konsiderojë këto paralajmërime të parëndësishme për momentin (ruani borxhin teknik për më vonë) dhe nuk do t'i shfaqë më ato. Analizuesi krijon një skedar të veçantë ku ruan informacione rreth gabimeve që nuk janë ende interesante. Dhe tani PVS-Studio do të lëshojë paralajmërime vetëm për kodin e ri ose të ndryshuar. Për më tepër, e gjithë kjo zbatohet me zgjuarsi. Nëse, për shembull, një rresht bosh shtohet në fillim të skedarit të kodit burimor, atëherë analizuesi kupton që, në fakt, asgjë nuk ka ndryshuar dhe do të vazhdojë të heshtë. Ky skedar shënjimi mund të vendoset në një sistem kontrolli të versionit. Skedari është i madh, por ky nuk është problem, pasi nuk ka kuptim ta ruani shpesh.

Tani të gjithë programuesit do të shohin paralajmërime që lidhen vetëm me kodin e ri ose të ndryshuar. Kështu, mund të filloni të përdorni analizuesin, siç thonë ata, nga dita tjetër. Dhe ju mund të ktheheni në borxhin teknik më vonë, dhe gradualisht të korrigjoni gabimet dhe të konfiguroni analizuesin.

Pra, problemi i parë me zbatimin e analizatorit në një projekt të madh të vjetër është zgjidhur. Tani le të kuptojmë se çfarë të bëjmë me borxhin teknik.

Rregullime të gabimeve dhe rifaktorizim

Gjëja më e thjeshtë dhe më e natyrshme është të lëmë mënjanë pak kohë për të analizuar paralajmërimet e analizuesve të shtypura masivisht dhe gradualisht t'i trajtojmë ato. Diku duhet të rregulloni gabimet në kod, diku duhet të rifaktoroni për t'i thënë analizuesit që kodi nuk është problematik. Shembull i thjeshtë:

if (a = b)

Shumica e përpiluesve dhe analizuesve C++ ankohen për një kod të tillë, pasi ekziston një probabilitet i lartë që ata në të vërtetë donin të shkruanin (a == b). Por ka një marrëveshje të pashprehur, dhe kjo zakonisht shënohet në dokumentacion, se nëse ka kllapa shtesë, atëherë konsiderohet se programuesi e ka shkruar qëllimisht një kod të tillë dhe nuk ka nevojë të betohet. Për shembull, në dokumentacionin PVS-Studio për diagnostikim V559 (CWE-481) është shkruar qartë se rreshti i mëposhtëm do të konsiderohet i saktë dhe i sigurt:

if ((a = b))

Një shembull tjetër. A është harruar në këtë kod C++? pushim apo jo?

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

Analizatori PVS-Studio do të lëshojë një paralajmërim këtu V796 (CWE-484). Ky mund të mos jetë një gabim, në të cilin rast duhet t'i jepni analizuesit një sugjerim duke shtuar atributin [[përmbysje]] ose për shembull __atribut__((përmbysje)):

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

Mund të thuhet se ndryshime të tilla të kodit nuk e rregullojnë gabimin. Po, kjo është e vërtetë, por bën dy gjëra të dobishme. Së pari, raporti i analizuesit shpëton nga pozitivet e rreme. Së dyti, kodi bëhet më i kuptueshëm për njerëzit e përfshirë në mirëmbajtjen e tij. Dhe kjo është shumë e rëndësishme! Vetëm për këtë, ia vlen të kryhen rifaktorime të vogla për ta bërë kodin më të qartë dhe më të lehtë për t'u ruajtur. Meqenëse analizuesi nuk e kupton nëse nevojitet apo jo "thyerja", do të jetë e paqartë edhe për programuesit e tjerë.

Përveç rregullimeve të gabimeve dhe rifaktorimeve, ju mund të shtypni në mënyrë specifike paralajmërimet e dukshme të rreme të analizuesit. Disa diagnostifikime të parëndësishme mund të çaktivizohen. Për shembull, dikush mendon se paralajmërimet janë të kota V550 rreth krahasimit të vlerave float/dyfishe. Dhe disa i klasifikojnë ato si të rëndësishme dhe të denjë për studim [7]. Cilat paralajmërime konsiderohen të rëndësishme dhe cilat jo, varet nga ekipi i zhvillimit për të vendosur.

Ka mënyra të tjera për të shtypur alarmet e rreme. Për shembull, shënimi makro u përmend më herët. E gjithë kjo përshkruhet më në detaje në dokumentacion. Gjëja më e rëndësishme është të kuptoni se nëse gradualisht dhe sistematikisht i afroheni punës me false pozitive, nuk ka asgjë të keqe me to. Shumica dërrmuese e paralajmërimeve jointeresante zhduken pas konfigurimit dhe mbeten vetëm vendet që kërkojnë vërtet studim të kujdesshëm dhe disa ndryshime në kod.

Gjithashtu, ne gjithmonë i ndihmojmë klientët tanë të krijojnë PVS-Studio nëse lindin ndonjë vështirësi. Për më tepër, kishte raste kur ne vetë eliminuam paralajmërimet e rreme dhe korrigjuam gabimet [8]. Për çdo rast, vendosa të përmend se ky opsion për bashkëpunim të zgjeruar është gjithashtu i mundur :).

Metoda me arpion

Ekziston një qasje tjetër interesante për të përmirësuar gradualisht cilësinë e kodit duke eliminuar paralajmërimin e analizuesit statik. Në fund të fundit, numri i paralajmërimeve mund të ulet vetëm.

Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin

Numri i paralajmërimeve të lëshuara nga analizuesi statik regjistrohet. Porta e cilësisë është konfiguruar në atë mënyrë që tani mund të futni vetëm një kod që nuk rrit numrin e operacioneve. Si rezultat, procesi i uljes graduale të numrit të alarmeve fillon duke rregulluar analizuesin dhe korrigjimin e gabimeve.

Edhe nëse një person dëshiron të mashtrojë pak dhe vendos të kalojë portën e cilësisë jo duke eliminuar paralajmërimet në kodin e tij të ri, por duke përmirësuar kodin e vjetër të palës së tretë, kjo nuk është e frikshme. E njëjta gjë, arpion rrotullohet në një drejtim dhe gradualisht numri i defekteve do të ulet. Edhe nëse një person nuk dëshiron të rregullojë defektet e tij të reja, ai ende do të duhet të përmirësojë diçka në kodin fqinj. Në një moment, mënyrat e thjeshta për të reduktuar numrin e paralajmërimeve përfundojnë dhe vjen një moment kur gabimet e vërteta do të rregullohen.

Kjo metodologji përshkruhet më në detaje në një artikull shumë interesant nga Ivan Ponomarev "Zbatoni analizën statike në proces, në vend që të kërkoni për gabime me të", të cilën unë rekomandoj ta lexojë për këdo që është i interesuar në përmirësimin e cilësisë së kodit.

Autori i artikullit gjithashtu ka një raport për këtë temë: "Analiza statike e vazhdueshme".

Përfundim

Shpresoj që pas këtij artikulli, lexuesit do t'i pranojnë më shumë mjetet e analizës statike dhe do të duan t'i zbatojnë ato në procesin e zhvillimit. Nëse keni ndonjë pyetje, ne jemi gjithmonë të gatshëm këshillë përdoruesit e analizuesit tonë statik PVS-Studio dhe ndihmojnë në zbatimin e tij.

Ekzistojnë dyshime të tjera tipike nëse analiza statike mund të jetë vërtet e përshtatshme dhe e dobishme. Unë u përpoqa të shpërndaj shumicën e këtyre dyshimeve në botimin "Arsyet për të futur analizuesin statik të kodit PVS-Studio në procesin e zhvillimit" [9].

Faleminderit për vëmendjen tuaj dhe ejani shkarko dhe provoni analizuesin PVS-Studio.

Lidhje shtesë

  1. Andrey Karpov. Si mund të shoh shpejt paralajmërimet interesante që analizuesi PVS-Studio prodhon për kodin C dhe C++?
  2. Wikipedia. Teorema e Rajsit.
  3. Andrey Karpov, Victoria Khanieva. Përdorimi i mësimit të makinerive në analizën statike të kodit burimor të programit.
  4. PVS-Studio. Dokumentacioni. Cilësimet shtesë të diagnostikimit.
  5. Andrey Karpov. Karakteristikat e analizuesit PVS-Studio duke përdorur shembullin e Bibliotekave Core EFL, 10-15% false pozitive.
  6. PVS-Studio. Dokumentacioni. Shtypja masive e mesazheve të analizuesit.
  7. Ivan Andryashin. Rreth asaj se si testuam analizën statike në projektin tonë të një simulatori arsimor të kirurgjisë endovaskulare me rreze X.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Si e përmirësoi ekipi i PVS-Studio kodin Unreal Engine.
  9. Andrey Karpov. Arsyet për të futur analizuesin statik të kodit PVS-Studio në procesin e zhvillimit.

Si të zbatoni një analizues të kodit statik në një projekt të trashëguar pa demotivuar ekipin

Nëse dëshironi ta ndani këtë artikull me një audiencë anglishtfolëse, ju lutemi përdorni lidhjen e përkthimit: Andrey Karpov. Si të futni një analizues të kodit statik në një projekt të trashëguar dhe të mos dekurajoni ekipin.

Burimi: www.habr.com

Shto një koment