ProHoster > Blogi > antaminen > Kuinka määrittää PVS-Studio Travis CI:ssä käyttämällä esimerkkiä PSP-pelikonsoliemulaattorista
Kuinka määrittää PVS-Studio Travis CI:ssä käyttämällä esimerkkiä PSP-pelikonsoliemulaattorista
Travis CI on hajautettu verkkopalvelu ohjelmistojen rakentamiseen ja testaamiseen, joka käyttää GitHubia lähdekoodin isännöinnissä. Yllä olevien käyttöskenaarioiden lisäksi voit lisätä omiasi laajojen konfigurointivaihtoehtojen ansiosta. Tässä artikkelissa määritämme Travis CI:n toimimaan PVS-Studion kanssa käyttämällä PPSSPP-koodiesimerkkiä.
Esittely
Travis CI on verkkopalvelu ohjelmistojen rakentamiseen ja testaamiseen. Sitä käytetään yleensä jatkuvan integroinnin yhteydessä.
PPSSPP - PSP-pelikonsolin emulaattori. Ohjelma pystyy jäljittelemään minkä tahansa pelin käynnistämistä Sony PSP:lle tarkoitetuista levykuvista. Ohjelma julkaistiin 1. PPSSPP on lisensoitu GPL v2012:lla. Kuka tahansa voi tehdä parannuksia projektin lähdekoodi.
PVS-studio — staattinen koodianalysaattori virheiden ja mahdollisten haavoittuvuuksien etsimiseen ohjelmakoodista. Tässä artikkelissa käynnistämme vaihteeksi PVS-Studion paikallisesti kehittäjän koneella, vaan pilvessä ja etsimme virheitä PPSSPP:stä.
Mennään sivustolle Travis CI. Kun valtuutus on tehty GitHub-tililläsi, näemme luettelon arkistoista:
Testiä varten haaroitin PPSSPP:n.
Aktivoimme arkiston, jonka haluamme kerätä:
Tällä hetkellä Travis CI ei voi rakentaa projektiamme, koska rakentamiseen ei ole ohjeita. On siis asetusten aika.
Analyysin aikana jotkut muuttujat ovat hyödyllisiä meille, esimerkiksi PVS-Studion avain, jota ei ole toivottavaa määrittää asetustiedostossa. Lisätään siis ympäristömuuttujat Travis CI:n koontiasetusten avulla:
Tarvitaan:
PVS_USERNAME - käyttäjätunnus
PVS_KEY - avain
MAIL_USER - sähköposti, jota käytetään raportin lähettämiseen
MAIL_PASSWORD - sähköpostin salasana
Kaksi viimeistä ovat valinnaisia. Näitä käytetään tulosten lähettämiseen postitse. Jos haluat jakaa raportin muulla tavalla, sinun ei tarvitse ilmoittaa niitä.
Joten olemme lisänneet tarvitsemamme ympäristömuuttujat:
Luodaan nyt tiedosto .travis.yml ja aseta se projektin ytimeen. PPSSPP:llä oli jo konfiguraatiotiedosto Travis CI:lle, mutta se oli liian suuri ja täysin sopimaton esimerkkiin, joten jouduimme yksinkertaistamaan sitä suuresti ja jättämään vain peruselementit.
Ilmoitetaan ensin kieli, Ubuntu Linuxin versio, jota haluamme käyttää virtuaalikoneessa, ja tarvittavat paketit rakentamiseen:
Kaikki listatut paketit tarvitaan yksinomaan PPSSPP:tä varten.
Nyt osoitamme kokoonpanomatriisin:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Hieman lisää jaksosta matriisi. Travis CI:ssä on kaksi tapaa luoda koontiasetuksia: ensimmäinen on määrittää luettelo kääntäjistä, käyttöjärjestelmätyypeistä, ympäristömuuttujista jne., minkä jälkeen luodaan matriisi kaikista mahdollisista yhdistelmistä; toinen on selkeä osoitus matriisista. Voit tietysti yhdistää nämä kaksi lähestymistapaa ja lisätä ainutlaatuisen tapauksen tai päinvastoin sulkea sen pois osion avulla sulkea. Voit lukea tästä lisää kohdasta Travis CI:n dokumentaatio.
Jäljelle jää vain projektikohtaiset asennusohjeet:
Travis CI:n avulla voit lisätä omia komentojasi virtuaalikoneen eri elämänvaiheisiin. osio ennen_asennusta suoritetaan ennen pakettien asentamista. Sitten asentaa, joka seuraa pakettien asennusta luettelosta addons.aptjonka ilmoitimme edellä. Itse kokoonpano tapahtuu sisään käsikirjoitus. Jos kaikki meni hyvin, löydämme itsemme jälkeen_menestyksen (Tässä osiossa suoritamme staattisen analyysin). Nämä eivät ole kaikkia vaiheita, joita voidaan muokata, jos tarvitset lisää, sinun kannattaa katsoa sisään Travis CI:n dokumentaatio.
Lukemisen helpottamiseksi komennot sijoitettiin erilliseen komentosarjaan .travis.sh, joka sijoitetaan projektin juureen.
Nyt siirrymme suoraan PVS-Studion automaattisen käynnistyksen asettamiseen Travis CI:ssä. Ensin meidän on asennettava PVS-Studio-paketti järjestelmään:
travis_install() {
if [ "$CXX" = "g++" ]; then
sudo apt-get install -qq g++-4.8
fi
if [ "$PVS_ANALYZE" = "Yes" ]; then
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
libio-socket-ssl-perl
libnet-ssleay-perl
fi
download_extract
"https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz"
cmake-3.6.2-Linux-x86_64.tar.gz
}
Toiminnon alussa travis_install asennamme tarvitsemamme kääntäjät käyttämällä ympäristömuuttujia. Sitten jos muuttuja $PVS_ANALYZE tallentaa arvoa Kyllä (ilmoitimme sen kohdassa env rakennusmatriisin määrityksen aikana), asennamme paketin pvs-studio. Tämän lisäksi ilmoitetaan myös paketit libio-socket-ssl-perl и libnet-ssleay-perlNe ovat kuitenkin pakollisia tulosten postittamiseen, joten ne eivät ole välttämättömiä, jos olet valinnut toisen tavan toimittaa raporttisi.
Toiminto lataus_ote lataa ja purkaa määritetyn arkiston:
On aika koota projekti. Tämä tapahtuu osiossa käsikirjoitus:
travis_script() {
if [ -d cmake-3.6.2-Linux-x86_64 ]; then
export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
fi
CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
cmake $CMAKE_ARGS CMakeLists.txt
make
}
Itse asiassa tämä on yksinkertaistettu alkuperäinen kokoonpano, lukuun ottamatta näitä rivejä:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Tässä koodin osassa määritimme cmake lippu käännöskomentojen vientiä varten. Tämä on välttämätöntä staattisen koodin analysaattorille. Voit lukea tästä lisää artikkelista "Kuinka käyttää PVS-Studioa Linuxissa ja macOS:ssä".
Jos kokoonpano onnistui, niin päästään jälkeen_menestyksen, jossa suoritamme staattisen analyysin:
Ensimmäinen rivi luo lisenssitiedoston käyttäjänimestä ja avaimesta, jotka määritimme heti Travis CI -ympäristömuuttujia määritettäessä.
Toinen rivi aloittaa analyysin suoraan. Lippu -j määrittää analyysin säikeiden lukumäärän, lippu -l osoittaa lisenssiä, lippua -o määrittää tiedoston lokien tulostamista varten ja lipun -DisableLicenseExpirationCheck vaaditaan kokeiluversioille, koska oletuksena pvs-studio-analysaattori varoittaa käyttäjää, että käyttöoikeus on vanhentumassa. Voit estää tämän tapahtuman määrittämällä tämän lipun.
Lokitiedosto sisältää raakatulosteen, jota ei voida lukea ilman muuntamista, joten sinun on ensin tehtävä tiedosto luettavaksi. Viedään lokit läpi plog-muunnin, ja tulos on html-tiedosto.
Tässä esimerkissä päätin lähettää raportit postitse komennolla lähettää sähköpostia.
Tuloksena saimme seuraavan tiedoston .travis.sh:
#/bin/bash
travis_before_install() {
git submodule update --init --recursive
}
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
travis_install() {
if [ "$CXX" = "g++" ]; then
sudo apt-get install -qq g++-4.8
fi
if [ "$PVS_ANALYZE" = "Yes" ]; then
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
libio-socket-ssl-perl
libnet-ssleay-perl
fi
download_extract
"https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.tar.gz"
cmake-3.6.2-Linux-x86_64.tar.gz
}
travis_script() {
if [ -d cmake-3.6.2-Linux-x86_64 ]; then
export PATH=$(pwd)/cmake-3.6.2-Linux-x86_64/bin:$PATH
fi
CMAKE_ARGS="-DHEADLESS=ON ${CMAKE_ARGS}"
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
cmake $CMAKE_ARGS CMakeLists.txt
make
}
travis_after_success() {
if [ "$PVS_ANALYZE" = "Yes" ]; then
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic
-o PVS-Studio-${CC}.log
--disableLicenseExpirationCheck
plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
sendemail -t [email protected]
-u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT"
-s smtp.gmail.com:587
-xu $MAIL_USER
-xp $MAIL_PASSWORD
-o tls=yes
-f $MAIL_USER
-a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
fi
}
set -e
set -x
$1;
Nyt on aika työntää muutokset git-tietovarastoon, minkä jälkeen Travis CI suorittaa koontiversion automaattisesti. Napsauta "ppsspp" päästäksesi koontiraportteihin:
Näemme yleiskatsauksen nykyisestä rakenteesta:
Jos rakentaminen onnistuu, saamme sähköpostin staattisen analyysin tuloksista. Postitus ei tietenkään ole ainoa tapa saada raportti. Voit valita minkä tahansa toteutustavan. Mutta on tärkeää muistaa, että kun rakennus on valmis, virtuaalikoneen tiedostoihin ei ole mahdollista päästä käsiksi.
Virheyhteenveto
Olemme onnistuneesti suorittaneet vaikeimman osan. Varmistetaan nyt, että kaikki ponnistelumme ovat sen arvoisia. Katsotaanpa joitain mielenkiintoisia kohtia minulle postitse saapuneesta staattisen analyysin raportista (en turhaan ilmoittanut sitä).
PVS-Studion varoitus: V597 Kääntäjä voi poistaa "memset"-funktiokutsun, jota käytetään "summa"-puskurin tyhjentämiseen. RtlSecureZeroMemory()-toimintoa tulee käyttää yksityisten tietojen poistamiseen. sha1.cpp 325
Tämä koodinpätkä sijaitsee suojatussa hajautusmoduulissa, mutta se sisältää vakavan tietoturvavirheen (CWE-14). Katsotaanpa kokoonpanoluetteloa, joka luodaan Debug-versiota käännettäessä:
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Kaikki on kunnossa ja toimii memeset suoritetaan, mikä korvaa tärkeät tiedot RAM-muistissa, mutta älä iloitse vielä. Katsotaanpa Release-version kokoonpanoluetteloa optimoinnin kanssa:
Kuten listauksesta voidaan nähdä, kääntäjä jätti kutsun huomioimatta memeset. Tämä johtuu siitä, että funktiossa sha1 puhelun jälkeen memeset ei enää viitata rakenteeseen ctx. Siksi kääntäjä ei näe mitään järkeä tuhlata prosessorin aikaa korvaamaan muistia, jota ei käytetä tulevaisuudessa. Voit korjata tämän käyttämällä toimintoa RtlSecureZeroMemory tai samanlainen hänelle.
static u32 sceAudioOutputPannedBlocking
(u32 chan, int leftvol, int rightvol, u32 samplePtr) {
int result = 0;
// For some reason, this is the only one that checks for negative.
if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
....
} else {
if (leftvol >= 0) {
chans[chan].leftVolume = leftvol;
}
if (rightvol >= 0) {
chans[chan].rightVolume = rightvol;
}
chans[chan].sampleAddress = samplePtr;
result = __AudioEnqueue(chans[chan], chan, true);
}
}
PVS-Studion varoitus: V547 Lauseke 'leftvol >= 0' on aina tosi. sceAudio.cpp 120
Kiinnitä ensin huomiota muuhun haaraan if. Koodi suoritetaan vain, jos kaikki ehdot täyttyvät vasen vol > 0xFFFF || rightvol > 0xFFFF || vasen vol < 0 || oikea tilavuus < 0 tulee valheeksi. Siksi saamme seuraavat väitteet, jotka pätevät else-haaraan: leftvol <= 0xFFFF, rightvol <= 0xFFFF, vasen vol >= 0 и oikea tila >= 0. Huomaa kaksi viimeistä väitettä. Onko järkevää tarkistaa, mikä on välttämätön ehto tämän koodinpalan suorittamiselle?
Joten voimme turvallisesti poistaa nämä ehdolliset lauseet:
static u32 sceAudioOutputPannedBlocking
(u32 chan, int leftvol, int rightvol, u32 samplePtr) {
int result = 0;
// For some reason, this is the only one that checks for negative.
if (leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0) {
....
} else {
chans[chan].leftVolume = leftvol;
chans[chan].rightVolume = rightvol;
chans[chan].sampleAddress = samplePtr;
result = __AudioEnqueue(chans[chan], chan, true);
}
}
Toinen skenaario. Näiden ylimääräisten olosuhteiden takana on jonkinlainen virhe. Ehkä he eivät tarkistaneet, mitä vaadittiin.
V501 Kohteen '||' vasemmalla ja oikealla puolella on identtiset alilausekkeet '!Memory::IsValidAddress(psmfData)'. operaattori. scePsmf.cpp 703
Kiinnitä huomiota sisällä olevaan sekkiin if. Eikö ole outoa, että tarkistamme, onko osoite oikea? psmfData, kaksi kertaa niin paljon? Joten tämä tuntuu minusta oudolta... Itse asiassa tämä on tietysti kirjoitusvirhe, ja idea oli tarkistaa molemmat syöttöparametrit.
extern void ud_translate_att(
int size = 0;
....
if (size == 8) {
ud_asmprintf(u, "b");
} else if (size == 16) {
ud_asmprintf(u, "w");
} else if (size == 64) {
ud_asmprintf(u, "q");
}
....
}
PVS-Studion varoitus: V547 Lauseke "koko == 8" on aina epätosi. syn-att.c 195
Tämä virhe sijaitsee kansiossa ext, joten se ei varsinaisesti liity projektiin, mutta vika löydettiin ennen kuin huomasin sen, joten päätin jättää sen. Loppujen lopuksi tämä artikkeli ei käsittele virheiden tarkistamista, vaan integraatiota Travis CI:n kanssa, eikä analysaattorin konfigurointia suoritettu.
muuttuja koko alustetaan vakiolla, mutta sitä ei käytetä koodissa ollenkaan operaattoriin asti if, joka tietysti antaa väärä kun tarkastelimme ehtoja, koska kuten muistamme, koko yhtä suuri kuin nolla. Myöskään myöhemmissä tarkastuksissa ei ole mitään järkeä.
Ilmeisesti koodinpätkän kirjoittaja unohti ylikirjoittaa muuttujan koko sitä ennen.
stop
Tähän todennäköisesti päädymme virheisiin. Tämän artikkelin tarkoituksena on esitellä PVS-Studion työtä yhdessä Travis CI:n kanssa, eikä analysoida projektia mahdollisimman perusteellisesti. Jos haluat suurempia ja kauniimpia virheitä, voit aina ihailla niitä täällä :).
Johtopäätös
Käyttämällä verkkopalveluita projektien rakentamiseen yhdessä inkrementaalisen analyysin kanssa voit löytää monia ongelmia heti koodin yhdistämisen jälkeen. Yksi koontiversio ei kuitenkaan välttämättä riitä, joten testauksen asettaminen yhdessä staattisen analyysin kanssa parantaa koodin laatua merkittävästi.