Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team

Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team
Madaling subukan ang isang static code analyzer. Ngunit upang maipatupad ito, lalo na sa pagbuo ng isang malaking lumang proyekto, ay nangangailangan ng kasanayan. Kung nagawa nang hindi tama, maaaring magdagdag ng trabaho ang analyzer, pabagalin ang pag-unlad, at i-demotivate ang team. Pag-usapan natin nang maikli ang tungkol sa kung paano maayos na lapitan ang pagsasama ng static na pagsusuri sa proseso ng pag-unlad at simulang gamitin ito bilang bahagi ng CI/CD.

Pagpapakilala

Kamakailan ay naakit ang aking pansin sa publikasyon "Pagsisimula Sa Static na Pagsusuri Nang Hindi Nababalot ang Koponan". Sa isang banda, ito ay isang magandang artikulo na karapat-dapat na makilala. Sa kabilang banda, tila sa akin ay hindi pa rin ito nagbibigay ng kumpletong sagot sa kung paano walang sakit na ipatupad ang static na pagsusuri sa isang proyekto na may maraming ng legacy code. Sinasabi ng artikulo na Maaari kang tumanggap ng teknikal na utang at magtrabaho lamang sa bagong code, ngunit walang sagot sa kung ano ang gagawin sa teknikal na utang na ito sa ibang pagkakataon.

Ang aming PVS-Studio team ay nag-aalok ng pananaw nito sa paksang ito. Tingnan natin kung paano lumitaw ang problema sa pagpapatupad ng isang static na code analyzer sa unang lugar, kung paano malalampasan ang problemang ito, at kung paano unti-unting alisin ang teknikal na utang.

Mga isyu

Karaniwang hindi mahirap ilunsad at makita kung paano gumagana ang isang static analyzer [1]. Maaari kang makakita ng mga kawili-wiling error o kahit na nakakatakot na potensyal na kahinaan sa code. Maaari mo ring ayusin ang isang bagay, ngunit pagkatapos ay maraming mga programmer ang sumuko.

Ang lahat ng static analyzer ay gumagawa ng mga maling positibo. Ito ay isang tampok ng static code analysis methodology, at walang magagawa tungkol dito. Sa pangkalahatang kaso, ito ay isang hindi malulutas na problema, gaya ng kinumpirma ng theorem ni Rice [2]. Ang mga algorithm ng machine learning ay hindi rin makakatulong [3]. Kahit na ang isang tao ay hindi palaging masasabi kung ito o ang code na iyon ay mali, hindi mo dapat asahan ito mula sa programa :).

Ang mga maling positibo ay hindi isang problema kung ang static na analyzer ay na-configure na:

  • Naka-disable ang mga hindi nauugnay na hanay ng panuntunan;
  • Ang ilang mga hindi nauugnay na diagnostic ay hindi pinagana;
  • Kung C o C++ ang pinag-uusapan, minarkahan ang mga macro na naglalaman ng mga partikular na konstruksyon na nagdudulot ng mga walang kwentang babala na lumitaw sa bawat lugar kung saan ginagamit ang mga naturang macro;
  • Ang mga sariling function ay minarkahan na nagsasagawa ng mga aksyon na katulad ng mga function ng system (ang sarili nitong analogue memcpy o printf) [4];
  • Ang mga maling positibo ay partikular na hindi pinagana gamit ang mga komento;
  • At iba pa.

Sa kasong ito, maaari nating asahan ang mababang false positive rate na humigit-kumulang 10-15% [5]. Sa madaling salita, 9 sa 10 babala ng analyzer ay magsasaad ng totoong problema sa code, o kahit man lang "malakas ang amoy na code." Sumang-ayon, ang sitwasyong ito ay lubos na kaaya-aya, at ang analyzer ay isang tunay na kaibigan ng programmer.

Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team
Sa katotohanan, sa isang malaking proyekto, ang unang larawan ay magiging ganap na naiiba. Ang analyzer ay nagbibigay ng daan-daan o libu-libong mga babala para sa legacy code. Imposibleng mabilis na maunawaan kung alin sa mga babalang ito ang may kaugnayan at alin ang hindi. Hindi makatwiran na umupo at simulan ang pagharap sa lahat ng mga babalang ito, dahil ang pangunahing gawain sa kasong ito ay titigil sa loob ng mga araw o linggo. Karaniwan, hindi kayang bayaran ng isang koponan ang gayong senaryo. Magkakaroon din ng malaking bilang ng mga diff na sumisira sa kasaysayan ng pagbabago. At ang mabilis na malawakang pag-edit ng napakaraming fragment sa code ay hindi maiiwasang magreresulta sa mga bagong typo at error.

At ang pinakamahalaga, ang gayong tagumpay sa paglaban sa mga babala ay walang kabuluhan. Sumang-ayon na dahil matagumpay na tumatakbo ang proyekto sa loob ng maraming taon, karamihan sa mga kritikal na error dito ay naitama na. Oo, napakamahal ng mga pag-aayos na ito, kailangang i-debug, makatanggap ng negatibong feedback ng user tungkol sa mga bug, at iba pa. Makakatulong ang isang static na analyzer na ayusin ang marami sa mga error na ito sa yugto ng coding, nang mabilis at mura. Ngunit sa ngayon, isang paraan o iba pa, ang mga error na ito ay naayos na, at ang analyzer ay pangunahing nakakakita ng mga hindi kritikal na error sa lumang code. Maaaring hindi gamitin ang code na ito, maaaring bihira itong gamitin, at maaaring hindi humantong sa kapansin-pansing mga kahihinatnan ang isang error dito. Marahil sa isang lugar ang anino mula sa pindutan ay maling kulay, ngunit hindi ito nakakasagabal sa paggamit ng sinuman sa produkto.

Siyempre, kahit maliit na pagkakamali ay pagkakamali pa rin. At kung minsan ang isang pagkakamali ay maaaring magtago ng isang tunay na kahinaan. Gayunpaman, ang pagbibigay ng lahat at paggugol ng mga araw/linggo sa pagharap sa mga depekto na halos hindi nagpapakita ng kanilang mga sarili ay mukhang isang kahina-hinalang ideya.

Ang mga programmer ay tumingin, tumingin, tumingin sa lahat ng mga babalang ito tungkol sa lumang working code... At sa tingin nila: magagawa natin nang walang static na pagsusuri. Sumulat tayo ng ilang bagong kapaki-pakinabang na pag-andar.

Sa sarili nilang paraan, tama sila. Naisip nila na kailangan muna nilang alisin ang lahat ng mga babalang ito. Saka lamang sila makikinabang sa regular na paggamit ng code analyzer. Kung hindi, ang mga bagong babala ay malulunod lamang sa mga luma, at walang sinuman ang papansin sa kanila.

Ito ay ang parehong pagkakatulad sa mga babala ng compiler. Ito ay hindi walang dahilan na inirerekumenda nila na panatilihin ang bilang ng mga babala ng compiler sa 0. Kung mayroong 1000 na mga babala, kung gayon kapag mayroong 1001, walang sinuman ang magbibigay pansin dito, at hindi malinaw kung saan hahanapin ang pinakabagong babala na ito.

Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team
Ang pinakamasamang bagay sa kuwentong ito ay kung ang isang tao mula sa itaas sa sandaling ito ay pumipilit sa iyo na gumamit ng static na pagsusuri ng code. Ito ay magpapapahina lamang sa koponan, dahil mula sa kanilang pananaw ay magkakaroon ng karagdagang bureaucratic complexity na humahadlang lamang. Walang titingin sa mga ulat ng analyzer, at ang lahat ng paggamit ay "sa papel" lamang. Yung. Pormal, ang pagsusuri ay binuo sa proseso ng DevOps, ngunit sa pagsasagawa, hindi ito nakikinabang sa sinuman. Nakarinig kami ng mga detalyadong kwento sa mga booth mula sa mga dumalo sa kumperensya. Ang ganitong karanasan ay maaaring huminto sa mga programmer na gumamit ng mga static na tool sa pagsusuri sa loob ng mahabang panahon, kung hindi man magpakailanman.

Pagpapatupad at pag-aalis ng teknikal na utang

Sa katunayan, walang mahirap o nakakatakot tungkol sa pagpapakilala ng static na pagsusuri kahit sa isang malaking lumang proyekto.

CI / CD

Bukod dito, ang analyzer ay maaaring agad na maging bahagi ng patuloy na proseso ng pag-unlad. Halimbawa, ang pamamahagi ng PVS-Studio ay naglalaman ng mga kagamitan para sa maginhawang pagtingin sa ulat sa format na kailangan mo, at mga abiso sa mga developer na nagsulat ng mga may problemang seksyon ng code. Para sa mga mas interesado sa paglunsad ng PVS-Studio mula sa mga CI/CD system, inirerekumenda kong pamilyar ka sa kaukulang seksyon dokumentasyon at isang serye ng mga artikulo:

Ngunit bumalik tayo sa isyu ng malaking bilang ng mga maling positibo sa mga unang yugto ng pagpapatupad ng mga tool sa pagsusuri ng code.

Pag-aayos ng kasalukuyang teknikal na utang at pagharap sa mga bagong babala

Nagbibigay-daan sa iyo ang mga modernong komersyal na static analyzer na pag-aralan lamang ang mga bagong babala na lumalabas sa bago o binagong code. Ang pagpapatupad ng mekanismong ito ay nag-iiba, ngunit ang kakanyahan ay pareho. Sa PVS-Studio static analyzer, ang pagpapaandar na ito ay ipinatupad bilang mga sumusunod.

Upang mabilis na simulan ang paggamit ng static na pagsusuri, iminumungkahi namin ang mga gumagamit ng PVS-Studio na gamitin ang mekanismo para sa malawakang pagsugpo sa mga babala [6]. Ang pangkalahatang ideya ay ang mga sumusunod. Inilunsad ng user ang analyzer at nakatanggap ng maraming babala. Dahil ang isang proyekto na binuo sa loob ng maraming taon ay buhay, umuunlad at kumita ng pera, malamang na hindi magkakaroon ng maraming babala sa ulat na nagpapahiwatig ng mga kritikal na depekto. Sa madaling salita, ang mga kritikal na bug ay naayos na sa isang paraan o iba pa gamit ang mas mahal na mga pamamaraan o salamat sa feedback mula sa mga customer. Alinsunod dito, ang lahat na kasalukuyang nahanap ng analyzer ay maaaring ituring na teknikal na utang, na hindi praktikal na subukang alisin kaagad.

Maaari mong sabihin sa PVS-Studio na isaalang-alang ang mga babalang ito na walang kaugnayan sa ngayon (i-save ang teknikal na utang para sa ibang pagkakataon), at hindi na ito magpapakita sa kanila. Lumilikha ang analyzer ng isang espesyal na file kung saan nagse-save ito ng impormasyon tungkol sa mga error na hindi pa kawili-wili. At ngayon ang PVS-Studio ay maglalabas lamang ng mga babala para sa bago o binagong code. Bukod dito, ang lahat ng ito ay ipinatupad nang matalino. Kung, halimbawa, ang isang walang laman na linya ay idinagdag sa simula ng source code file, pagkatapos ay nauunawaan ng analyzer na, sa katunayan, walang nagbago, at patuloy na tatahimik. Ang markup file na ito ay maaaring ilagay sa isang version control system. Malaki ang file, ngunit hindi ito problema, dahil walang saysay na iimbak ito nang madalas.

Ngayon ang lahat ng programmer ay makakakita ng mga babala na nauugnay lamang sa bago o binagong code. Kaya, maaari mong simulan ang paggamit ng analyzer, tulad ng sinasabi nila, mula sa susunod na araw. At maaari kang bumalik sa teknikal na utang sa ibang pagkakataon, at unti-unting iwasto ang mga error at i-configure ang analyzer.

Kaya, ang unang problema sa pagpapatupad ng analyzer sa isang malaking lumang proyekto ay nalutas na. Ngayon, alamin natin kung ano ang gagawin sa teknikal na utang.

Mga pag-aayos ng bug at refactorings

Ang pinakasimpleng at pinaka-natural na bagay ay ang maglaan ng ilang oras upang pag-aralan ang mga babala ng massively suppressed analyzer at unti-unting harapin ang mga ito. Sa isang lugar dapat mong ayusin ang mga error sa code, sa isang lugar dapat mong refactor upang sabihin sa analyzer na ang code ay hindi problema. Simpleng halimbawa:

if (a = b)

Karamihan sa mga compiler at analyzer ng C++ ay nagrereklamo tungkol sa naturang code, dahil malaki ang posibilidad na gusto talaga nilang magsulat (a == b). Ngunit mayroong isang hindi binibigkas na kasunduan, at ito ay karaniwang nabanggit sa dokumentasyon, na kung mayroong karagdagang mga panaklong, kung gayon ay isinasaalang-alang na ang programmer ay sadyang sumulat ng naturang code, at hindi na kailangang manumpa. Halimbawa, sa dokumentasyon ng PVS-Studio para sa mga diagnostic V559 (CWE-481) malinaw na nakasulat na ang sumusunod na linya ay ituturing na tama at ligtas:

if ((a = b))

Isa pang halimbawa. Nakalimutan ba ito sa C++ code na ito? masira o hindi?

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

Maglalabas ng babala ang PVS-Studio analyzer dito V796 (CWE-484). Maaaring hindi ito isang error, kung saan dapat mong bigyan ang parser ng pahiwatig sa pamamagitan ng pagdaragdag ng katangian [[fallthrough]] o, halimbawa, __attribute__((fallthrough)):

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

Masasabing hindi naaayos ng naturang mga pagbabago sa code ang bug. Oo, ito ay totoo, ngunit ito ay gumagawa ng dalawang kapaki-pakinabang na bagay. Una, inaalis ng ulat ng analyzer ang mga maling positibo. Pangalawa, ang code ay nagiging mas nauunawaan para sa mga taong kasangkot sa pagpapanatili nito. At ito ay napakahalaga! Para dito lamang, sulit na magsagawa ng mga maliliit na refactorings upang gawing mas malinaw at mas madaling mapanatili ang code. Dahil hindi naiintindihan ng analyzer kung kailangan o hindi ang "break", magiging malabo rin ito sa mga kapwa programmer.

Bilang karagdagan sa mga pag-aayos ng bug at refactorings, maaari mong partikular na sugpuin ang malinaw na maling mga babala ng analyzer. Maaaring hindi paganahin ang ilang hindi nauugnay na diagnostic. Halimbawa, iniisip ng isang tao na walang kabuluhan ang mga babala V550 tungkol sa paghahambing ng float/double value. At inuuri sila ng ilan bilang mahalaga at karapat-dapat pag-aralan [7]. Aling mga babala ang itinuturing na may-katuturan at kung alin ang hindi nakasalalay sa development team na magpasya.

Mayroong iba pang mga paraan upang sugpuin ang mga maling alerto. Halimbawa, ang macro markup ay nabanggit kanina. Ang lahat ng ito ay inilarawan nang mas detalyado sa dokumentasyon. Ang pinakamahalagang bagay ay maunawaan na kung unti-unti at sistematikong lumapit ka sa pagtatrabaho sa mga maling positibo, walang mali sa kanila. Ang karamihan sa mga hindi kawili-wiling mga babala ay nawawala pagkatapos ng pagsasaayos, at ang mga lugar lamang na talagang nangangailangan ng maingat na pag-aaral at ilang pagbabago sa code ang nananatili.

Gayundin, palagi naming tinutulungan ang aming mga kliyente na mag-set up ng PVS-Studio kung may mga problemang lumitaw. Bukod dito, may mga kaso kung saan kami mismo ang nag-alis ng mga maling babala at nagtama ng mga pagkakamali [8]. Kung sakali, nagpasya akong banggitin na ang pagpipiliang ito para sa pinalawig na kooperasyon ay posible din :).

Paraan ng ratchet

May isa pang kawili-wiling diskarte upang unti-unting mapabuti ang kalidad ng code sa pamamagitan ng pag-aalis ng babala ng static analyzer. Ang bottom line ay ang bilang ng mga babala ay maaari lamang bumaba.

Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team

Ang bilang ng mga babala na ibinigay ng static analyzer ay naitala. Ang gate ng kalidad ay na-configure sa paraang maaari ka lamang magpasok ng code na hindi nagpapataas ng bilang ng mga operasyon. Bilang resulta, ang proseso ng unti-unting pagbabawas ng bilang ng mga alarma ay magsisimula sa pamamagitan ng pagsasaayos ng analyzer at pagwawasto ng mga error.

Kahit na gusto ng isang tao na manloko ng kaunti at nagpasya na ipasa ang gate ng kalidad hindi sa pamamagitan ng pag-aalis ng mga babala sa kanyang bagong code, ngunit sa pamamagitan ng pagpapabuti ng lumang code ng third-party, hindi ito nakakatakot. Lahat ng pareho, ang ratchet ay umiikot sa isang direksyon, at unti-unting bababa ang bilang ng mga depekto. Kahit na ang isang tao ay hindi nais na ayusin ang kanyang sariling mga bagong depekto, kailangan pa rin niyang pagbutihin ang isang bagay sa kalapit na code. Sa ilang mga punto, ang mga madaling paraan upang bawasan ang bilang ng mga babala ay nagtatapos, at darating ang isang punto kung kailan aayusin ang mga totoong bug.

Ang pamamaraang ito ay inilarawan nang mas detalyado sa isang napaka-kagiliw-giliw na artikulo ni Ivan Ponomarev "Magpatupad ng static na pagsusuri sa proseso, sa halip na gamitin ito upang maghanap ng mga bug", na inirerekomenda kong basahin sa sinumang interesado sa pagpapabuti ng kalidad ng code.

Ang may-akda ng artikulo ay mayroon ding ulat sa paksang ito: "Patuloy na static na pagsusuri".

Konklusyon

Umaasa ako na pagkatapos ng artikulong ito, mas tatanggapin ng mga mambabasa ang mga static na tool sa pagsusuri at nais nilang ipatupad ang mga ito sa proseso ng pag-unlad. Kung mayroon kang anumang mga katanungan, kami ay laging handa payuhan mga gumagamit ng aming static analyzer PVS-Studio at tumulong sa pagpapatupad nito.

Mayroong iba pang mga karaniwang pagdududa tungkol sa kung ang static na pagsusuri ay talagang maginhawa at kapaki-pakinabang. Sinubukan kong iwaksi ang karamihan sa mga pag-aalinlangan na ito sa publikasyong "Mga dahilan upang ipakilala ang PVS-Studio static code analyzer sa proseso ng pag-unlad" [9].

Salamat sa iyong pansin at dumating i-download at subukan ang PVS-Studio analyzer.

Mga karagdagang link

  1. Andrey Karpov. Paano ko mabilis na makikita ang mga kawili-wiling babala na ginagawa ng PVS-Studio analyzer para sa C at C++ code?
  2. Wikipedia. Ang teorama ni Rice.
  3. Andrey Karpov, Victoria Khanieva. Paggamit ng machine learning sa static na pagsusuri ng source code ng program.
  4. PVS-Studio. Dokumentasyon. Mga karagdagang setting ng diagnostic.
  5. Andrey Karpov. Mga katangian ng PVS-Studio analyzer gamit ang halimbawa ng EFL Core Libraries, 10-15% false positive.
  6. PVS-Studio. Dokumentasyon. Mass suppression ng mga mensahe ng analyzer.
  7. Ivan Andryashin. Tungkol sa kung paano namin sinubukan ang static na pagsusuri sa aming proyekto ng isang pang-edukasyon na simulator ng X-ray endovascular surgery.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Paano pinahusay ng koponan ng PVS-Studio ang Unreal Engine code.
  9. Andrey Karpov. Mga dahilan para ipakilala ang static code analyzer na PVS-Studio sa proseso ng pagbuo.

Paano magpatupad ng static code analyzer sa isang legacy na proyekto nang hindi nade-demotivating ang team

Kung nais mong ibahagi ang artikulong ito sa isang madla na nagsasalita ng Ingles, mangyaring gamitin ang link ng pagsasalin: Andrey Karpov. Paano magpakilala ng static code analyzer sa isang legacy na proyekto at hindi para pahinain ang loob ng team.

Pinagmulan: www.habr.com

Magdagdag ng komento