Cum ajută analiza statică a codului în industria GameDev

( 4 decembrie 2020)

Industria jocurilor este în continuă evoluție și se dezvoltă mai repede decât un glonț accelerat. Împreună cu creșterea industriei, crește și complexitatea dezvoltării: baza de coduri este din ce în ce mai mare și numărul de bug-uri crește, de asemenea. Prin urmare, proiectele moderne de jocuri trebuie să acorde o atenție specială calității codului. Astăzi vom analiza una dintre modalitățile de a vă face codul mai decent, care este analiza statică, precum și modul în care PVS-Studio ajută în practică la dezvoltarea proiectului de joc de diferite dimensiuni.

„Cel mai important lucru pe care l-am făcut ca programator în ultimii ani este să urmărească agresiv analiza statică a codului. Chiar mai valoros decât sutele de erori grave pe care le-am prevenit este schimbarea mentalității cu privire la modul în care văd fiabilitatea software-ului și calitatea codului. ”- John Carmack

Lucrăm cu marii dezvoltatori de jocuri de mulți ani și în acest timp am reușit să facem o mulțime de lucruri interesante și utile pentru industria jocurilor. Nu este o mare surpriză, având în vedere lista a clienților noștri din industria jocurilor. Susținem în mod activ clienții noștri: să integreze PVS-Studio în propriul proces de dezvoltare, să remediem erorile găsite de analizor și chiar să facem caracteristici speciale personalizate.

În plus, facem o mulțime de dezvoltare independentă a analizorul în direcția GameDev, precum și promovarea PVS-Studio, spunând oamenilor despre erorile interesante pe care le-a găsit în diferite jocuri video.

Sigur, avem câteva povești interesante de spus. Acest articol va acoperi mai multe astfel de cazuri.

PVS-Studio and Unity

Unul dintre modurile în care promovăm produsul nostru este prin scrierea articolelor despre verificarea proiectelor deschise. Toată lumea beneficiază de aceste articole: un cititor are ocazia să verifice câteva erori neobișnuite într-un proiect familiar și să învețe ceva nou. În ceea ce privește echipa PVS-Studio, avem ocazia să arătăm munca realizată pe codul real, astfel încât dezvoltatorii de proiecte să poată afla despre erori și să le remedieze în prealabil.

Prima noastră cunoaștere majoră cu Unity a avut loc. în 2016, când dezvoltatorii acestui motor de joc au deschis codul sursă al mai multor componente, biblioteci și demonstrații în depozitul lor oficial. Nu e de mirare că nu am putut trece printr-un caz atât de atrăgător și am vrut să scriem un articol despre verificarea codului postat.

Apoi am aflat că codul Unity3D (la acel moment motorul era numit așa) a fost de foarte înaltă calitate. Dar totuși am reușit să găsim destul de multe erori grave în el. Au fost destui pentru a scrie un articol .

Doi ani mai târziu, s-a întâmplat un alt lucru – dezvoltatorii Unity au deschis codul motorului și editorul însuși. Și la fel ca și data precedentă, nu am putut să nu observăm acest lucru și am verificat codul sursă al motorului. Și nu a fost degeaba – am găsit, de asemenea, o grămadă de defecte captivante.

În același timp, intențiile noastre depășesc cu mult scrisul articole. Continuăm să lucrăm la PVS-Studio, iar GameDev este unul dintre cele mai semnificative domenii pentru dezvoltarea noastră. Prin urmare, dorim ca dezvoltatorii de jocuri Unity să poată obține cea mai bună analiză posibilă a proiectelor lor.

Unul dintre pașii pentru îmbunătățirea calității analizei proiectelor Unity a fost scrierea adnotărilor pentru metodele definite în Unity Scripting API .

Adnotarea metodei este un mecanism special utilizat în PVS-Studio. Acesta permite utilizatorului să furnizeze analizorului toate informațiile necesare despre o anumită metodă. Este scrisă într-un cod special de către dezvoltatorii înșiși ai analizorului (adică de noi).

Aceste informații pot fi de diferite tipuri. De exemplu: modul în care metoda poate afecta parametrii care i-au fost transferați, dacă poate aloca memorie și dacă returnează o valoare care trebuie tratată. Astfel, adnotarea permite analizorului să înțeleagă mai bine logica metodelor, permițându-i să detecteze erori noi și mai complexe.

Am scris deja un număr mare de adnotări diferite (de exemplu, pentru metodele din sistem namespace) și ne-am bucurat să le adăugăm adnotări de metodă din API-ul Unity Scripting.

Am început să extindem lista de adnotări cu o evaluare. Câte metode există în total? Care ar trebui să fie adnotate mai întâi? Au existat o mulțime de metode în total, așa că am decis să începem prin adnotarea celor mai frecvent utilizate.

Acesta este modul în care căutam metode populare: mai întâi, am adunat un grup de proiecte de la GitHub care folosesc caracteristicile Unity și apoi am folosit un utilitar auto-scris (bazat pe Roslyn) pentru a calcula apelurile metodele care ne-au interesat. Ca rezultat, am obținut o listă de clase ale căror metode au fost utilizate cel mai des:

  • UnityEngine.Vector3
  • UnityEngine.Mathf
  • UnityEngine.Debug
  • UnityEngine.GameObject
  • UnityEngine.Material
  • UnityEditor.EditorGUILayout
  • UnityEngine.Component
  • UnityEngine.Object
  • UnityEngine.GUILayout
  • UnityEngine.Quaternion

Apoi, a rămas pentru a adnota metodele acestor clase. Am creat un proiect de testare și am căutat în documentație pentru a obține cât mai multe informații despre aceste metode. De exemplu, am încercat să trecem nul ca diferite argumente pentru a vedea cum se va comporta programul.

În timpul acestor verificări, descopeream din când în când câteva informații interesante nedocumentate. Am găsit chiar și câteva erori remarcabile în motor. De exemplu, când rulăm următorul cod:

MeshRenderer renderer = cube.GetComponent();
Material m = renderer.material;
List<int> outNames = null;
m.GetTexturePropertyNameIDs(outNames);

editorul Unity se blochează (cel puțin în versiunea 2019.3.10f1). Desigur, este puțin probabil ca cineva să scrie un astfel de cod. Totuși, faptul că editorul Unity poate fi blocat prin rularea unui astfel de script este curios.

Deci, am avut adnotările scrise. După efectuarea analizei, am găsit imediat noi declanșări. De exemplu, analizorul a detectat un apel ciudat către metoda GetComponent :

void OnEnable()
{
GameObject uiManager = GameObject.Find("UIRoot"); if (uiManager)
{
uiManager.GetComponent();
}
}

Avertisment analizor: V3010 Este necesară utilizarea valorii returnate a funcției „GetComponent”. – ADIȚIONAL ÎN UIEditorWindow.cs ACTUAL 22

Metoda GetComponent implică returnarea unei valori specifice chiar datorită la numele său. Este logic să presupunem că această valoare ar trebui utilizată într-un fel. Acum, datorită noii adnotări, analizorul știe că un astfel de apel „nesupravegheat” la această metodă poate indica o eroare logică și avertizează despre aceasta.

Acesta nu este singurul avertisment care a apărut în setul testați proiectele după adăugarea de adnotări noi. Nu voi cita restul, pentru a nu face acest articol prea mare. Principalul lucru este că acum dezvoltarea proiectelor Unity folosind PVS-Studio vă permite să scrieți coduri mult mai sigure și mai curate fără erori.

Dacă doriți să citiți mai multe despre munca noastră cu adnotări pentru metodele Unity, iată articolul: Modul în care analizorul PVS-Studio a început să găsească și mai multe erori în proiectele Unity .

Unreal Engine 4

Când, în 2014, dezvoltatorii Unreal Motorul 4 a deschis codul sursă al motorului, pur și simplu nu am putut trece de acel proiect și am scris, de asemenea, un articol despre acesta. Dezvoltatorii de motoare au apreciat articolul și au remediat erorile pe care le-am găsit. Dar acest lucru nu a fost suficient pentru noi și am decis să încercăm să vindem licența pentru analizorul nostru către Epic Games.

Epic Games a fost interesat să-și îmbunătățească motorul cu PVS-Studio, așa că am fost de acord cu următoarele : reparăm singur codul Unreal Engine, astfel încât analizorul să nu emită niciun avertisment, iar băieții de la Epic Games ne cumpără licența și ne recompensează în plus pentru munca depusă.

De ce trebuiau să fie toate avertismentele? fix? Faptul este că se poate obține un beneficiu maxim din analiza statică prin corectarea erorilor chiar atunci când apar . Când vă verificați proiectul pentru prima dată, primiți de obicei câteva sute (și uneori mii) de avertismente. Dintre toate aceste declanșatoare ale analizorului, este ușor să pierdeți avertismentele emise pentru codul nou scris.

La prima vedere, această problemă poate fi rezolvată destul de ușor: trebuie doar să vă așezați și să parcurgeți întregul raport , corectând treptat erorile. Cu toate acestea, deși această metodă este mai intuitivă, poate dura ceva timp. Este mult mai convenabil și mai rapid să utilizați fișiere de suprimare.

Fișierele de suprimare sunt o caracteristică specială a PVS-Studio care vă permite să ascundeți avertismente ale analizorului într-un fișier special. Cu toate acestea, avertismentele ascunse nu vor apărea în jurnalele ulterioare: le puteți vizualiza separat.

După ce ați avut mai multe declanșări după prima verificare, puteți adăuga toate avertismentele detectate în fișierul de suprimare în câteva clicuri și veți obține un jurnal curat fără o singură intrare după următoarea verificare.

Acum că vechile avertismente nu mai sunt incluse în jurnal, puteți detecta cu ușurință un nou avertisment imediat când acesta apare. Iată ordinea acțiunilor: scrieți codul -> verificați-l cu analizorul -> localizați un nou avertisment -> remediați eroarea. Acesta este modul în care veți beneficia la maximum de utilizarea analizorului.

În același timp, nu uitați de avertismentele din fișierul de suprimare: acestea pot conține în continuare avertismente despre erori majore și vulnerabilități, la fel ca înainte. Prin urmare, ar trebui să reveniți la aceste avertismente și să le reduceți numărul în mod regulat.

Fără îndoială, acest scenariu este convenabil, dar dezvoltatorii de la Epic Games au dorit ca codul lor să fie reparat imediat, așa că au trecut sarcină pentru noi.

Și ne-am apucat de treabă. După ce am verificat codul proiectului, am găsit 1821 de avertismente de nivel_1 și nivel_2. Analizarea unui volum atât de mare de avertismente necesită o muncă serioasă și, pentru a facilita acest proces, am stabilit o analiză continuă a codului pe serverul nostru CI.

Arăta așa: în fiecare noapte pe serverul nostru, actualul a fost construită versiunea Unreal Engine 4 și imediat după compilare, analiza a fost pornită automat. Astfel, când băieții noștri veneau la muncă dimineața, aveau întotdeauna un nou raport de la analizor, care îi ajuta să urmărească progresul eliminării avertismentelor. În plus, acest sistem ne-a permis să verificăm în orice moment stabilitatea compilării, rulându-l manual pe server.

Întregul proces ne-a luat 17 zile lucrătoare. Programul pentru remedierea erorilor a fost după cum urmează:

De fapt, acest program nu reflectă pe deplin munca noastră. După ce am remediat toate avertismentele, am așteptat încă două zile ca aceștia să accepte ultimele noastre cereri de extragere. În tot acest timp, ultima versiune a Unreal Engine a fost verificată automat, care, la rândul său, a continuat să fie actualizată cu un nou cod. Deci, ce crezi că s-a întâmplat? În acele două zile, PVS-Studio a găsit încă patru erori în cod! Una dintre ele a fost crucială și ar putea duce la un comportament nedefinit.

Desigur, am remediat și acele erori. În acel moment, dezvoltatorilor Unreal Engine nu le mai rămăsese decât un singur lucru: configurarea analizei automate la locul lor, așa cum am făcut noi. Din acel moment, au început să vadă în fiecare zi avertismente care erau emise pentru codul pe care tocmai îl scriseseră. Acest lucru le-a permis să remedieze erorile din cod chiar atunci când au apărut – în primele etape de dezvoltare .

Puteți citi mai multe despre modul în care am lucrat la codul Unreal Engine în blog oficial Unreal Engine sau pe site-ul nostru .

Analiza diverse jocuri

Am menționat că am verificați diverse proiecte deschise și scrieți articole despre ele? Deci, acum avem o mulțime de articole similare despre proiecte de jocuri! Am scris despre jocuri precum VVVVVV , Space Engineers , Comandă & Conque r, osu! și chiar (un articol foarte timpuriu) Doom 3 . De asemenea, am compilat top 10 dintre cele mai interesante erori software din industria jocurilor video.

Deci, am verificat probabil majoritatea cunoscute motoare open source. Pe lângă Unity și Unreal Engine 4, proiecte precum Godot , Bullet , Amazon Lumberyard , Cry Engine V și mulți alții au intrat sub atenția noastră.

Cea mai bună parte din toate acestea este că multe dintre erorile pe care le-am descris au fost ulterior remediate chiar de dezvoltatorii proiectului. Este plăcut să simțiți că instrumentul pe care îl dezvoltați aduce beneficii reale, vizibile și tangibile lumii.

Puteți vizualiza o listă a tuturor articolelor noastre legate de dezvoltarea jocurilor video într-un fel sau altul pe un pagină specială a blogului nostru.

Concluzie

În acest moment, articolul meu se încheie. Vă doresc un cod curat și care funcționează corect fără erori și erori!

V-a interesat subiectul analizei statice? Doriți să verificați proiectul pentru erori? Încercați PVS-Studio .

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *