Travis CI ir izplatÄ«ts tÄ«mekļa pakalpojums programmatÅ«ras izveidei un testÄÅ”anai, kas izmanto GitHub kÄ pirmkoda mitinÄÅ”anu. Papildus iepriekÅ” minÄtajiem darbÄ«bas scenÄrijiem, pateicoties plaÅ”ajÄm konfigurÄcijas opcijÄm, varat pievienot arÄ« savus. Å ajÄ rakstÄ mÄs konfigurÄsim Travis CI darbam ar PVS-Studio, izmantojot PPSSPP koda piemÄru.
Ievads
Travis CI ir tÄ«mekļa pakalpojums programmatÅ«ras izveidei un testÄÅ”anai. To parasti izmanto kopÄ ar nepÄrtrauktas integrÄcijas praksi.
PPSSPP - PSP spÄļu konsoles emulators. Programma spÄj lÄ«dzinÄties jebkuras spÄles palaiÅ”anai no diska attÄliem, kas paredzÄti Sony PSP. Programma tika izlaista 1. gada 2012. novembrÄ«. PPSSPP ir licencÄts saskaÅÄ ar GPL v2. Ikviens var veikt uzlabojumus projekta pirmkods.
PVS-studija ā statisks kodu analizators kļūdu un iespÄjamo ievainojamÄ«bu meklÄÅ”anai programmas kodÄ. Å ajÄ rakstÄ mÄs izmaiÅu labad palaidÄ«sim PVS-Studio nevis lokÄli izstrÄdÄtÄja datorÄ, bet gan mÄkonÄ« un meklÄsim kļūdas PPSSPP.
Dosimies uz vietni Travis CI. PÄc autorizÄcijas, izmantojot savu GitHub kontu, mÄs redzÄsim krÄtuvju sarakstu:
PÄrbaudei es dakÅ”u PPSSPP.
MÄs aktivizÄjam repozitoriju, kuru vÄlamies apkopot:
Å obrÄ«d Travis CI nevar izveidot mÅ«su projektu, jo nav norÄdÄ«jumu par bÅ«vniecÄ«bu. TÄtad ir pienÄcis laiks konfigurÄt.
AnalÄ«zes laikÄ mums noderÄs daži mainÄ«gie, piemÄram, PVS-Studio atslÄga, ko nebÅ«tu vÄlams norÄdÄ«t konfigurÄcijas failÄ. TÄpÄc pievienosim vides mainÄ«gos, izmantojot Travis CI veidoÅ”anas iestatÄ«jumus:
Mums ir nepiecieŔams:
PVS_USERNAME ā lietotÄjvÄrds
PVS_KEY ā atslÄga
MAIL_USER ā e-pasts, kas tiks izmantots ziÅojuma nosÅ«tÄ«Å”anai
MAIL_PASSWORD ā e-pasta parole
PÄdÄjie divi nav obligÄti. Tie tiks izmantoti, lai nosÅ«tÄ«tu rezultÄtus pa pastu. Ja vÄlaties ziÅojumu izplatÄ«t citÄ veidÄ, jums tie nav jÄnorÄda.
TÄtad, mÄs esam pievienojuÅ”i mums nepiecieÅ”amos vides mainÄ«gos:
Tagad izveidosim failu .travis.yml un ievietojiet to projekta saknÄ. PPSSPP jau bija Travis CI konfigurÄcijas fails, tomÄr tas bija pÄrÄk liels un pilnÄ«gi nepiemÄrots piemÄram, tÄpÄc nÄcÄs to krietni vienkÄrÅ”ot un atstÄt tikai pamata elementus.
Vispirms norÄdÄ«sim valodu, Ubuntu Linux versiju, kuru vÄlamies izmantot virtuÄlajÄ maŔīnÄ, un bÅ«vÄÅ”anai nepiecieÅ”amÄs pakotnes:
Visas uzskaitÄ«tÄs pakotnes ir nepiecieÅ”amas tikai PPSSPP.
Tagad mÄs norÄdÄm montÄžas matricu:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Nedaudz vairÄk par sadaļu matrica. ProgrammÄ Travis CI ir divi veidi, kÄ izveidot veidoÅ”anas opcijas: pirmais ir norÄdÄ«t kompilatoru sarakstu, operÄtÄjsistÄmu tipus, vides mainÄ«gos utt., pÄc kura tiek Ä£enerÄta visu iespÄjamo kombinÄciju matrica; otrÄ ir skaidra matricas norÄde. Protams, jÅ«s varat apvienot Ŕīs divas pieejas un pievienot unikÄlu gadÄ«jumu vai, gluži pretÄji, to izslÄgt, izmantojot sadaļu izslÄgt. VairÄk par to varat lasÄ«t sadaÄ¼Ä Travis CI dokumentÄcija.
Atliek tikai nodroÅ”inÄt projektam specifiskas montÄžas instrukcijas:
Travis CI ļauj jums pievienot savas komandas dažÄdiem virtuÄlÄs maŔīnas dzÄ«ves posmiem. sadaļa pirms_instalÄÅ”anas tiek izpildÄ«ts pirms pakotÅu instalÄÅ”anas. Tad uzstÄdÄ«t, kas seko pakeÅ”u instalÄÅ”anai no saraksta addons.aptko mÄs norÄdÄ«jÄm iepriekÅ”. Pati montÄža notiek iekÅ”Ä scenÄrijs. Ja viss noritÄja labi, mÄs atrodamies pÄc_veiksmes (Å”ajÄ sadaÄ¼Ä mÄs veiksim statisko analÄ«zi). Å Ä«s nav visas darbÄ«bas, kuras var mainÄ«t, ja jums ir nepiecieÅ”ams vairÄk, tad jums vajadzÄtu ieskatÄ«ties Travis CI dokumentÄcija.
Lai atvieglotu lasÄ«Å”anu, komandas tika ievietotas atseviÅ”Ä·Ä skriptÄ .travis.sh, kas atrodas projekta saknÄ.
Pirms pakotÅu instalÄÅ”anas mÄs atjauninÄsim apakÅ”moduļus. Tas ir nepiecieÅ”ams, lai izveidotu PPSSPP. Pievienosim pirmo funkciju .travis.sh (Å emiet vÄrÄ paplaÅ”inÄjumu):
Tagad mÄs nonÄkam tieÅ”i pie PVS-Studio automÄtiskÄs palaiÅ”anas iestatÄ«Å”anas programmÄ Travis CI. Vispirms sistÄmÄ jÄinstalÄ PVS-Studio pakotne:
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
}
Funkcijas sÄkumÄ travis_install mÄs instalÄjam nepiecieÅ”amos kompilatorus, izmantojot vides mainÄ«gos. Tad, ja mainÄ«gais $PVS_ANALYZE saglabÄ vÄrtÄ«bu JÄ (mÄs to norÄdÄ«jÄm sadaÄ¼Ä env veidoÅ”anas matricas konfigurÄcijas laikÄ), mÄs instalÄjam pakotni pvs-studija. Papildus tam ir norÄdÄ«ti arÄ« iepakojumi libio-socket-ssl-perl Šø libnet-ssleay-perl, tomÄr tie ir nepiecieÅ”ami rezultÄtu nosÅ«tÄ«Å”anai pa pastu, tÄpÄc tie nav nepiecieÅ”ami, ja esat izvÄlÄjies citu atskaites piegÄdes metodi.
Funkcija download_extract lejupielÄdÄ un izpako norÄdÄ«to arhÄ«vu:
Ir pienÄcis laiks apvienot projektu. Tas notiek sadaÄ¼Ä scenÄrijs:
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
}
Faktiski Ŕī ir vienkÄrÅ”ota sÄkotnÄjÄ konfigurÄcija, izÅemot Ŕīs rindas:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Å ajÄ koda sadaÄ¼Ä mÄs iestatÄ«jÄm cmmake karodziÅÅ” kompilÄcijas komandu eksportÄÅ”anai. Tas ir nepiecieÅ”ams statiskÄ koda analizatoram. VairÄk par to varat lasÄ«t rakstÄ "KÄ palaist PVS-Studio operÄtÄjsistÄmÄs Linux un macOS".
Ja montÄža bija veiksmÄ«ga, tad tiekam pie pÄc_veiksmes, kur veicam statisko analÄ«zi:
PirmajÄ rindÄ tiek Ä£enerÄts licences fails no lietotÄjvÄrda un atslÄgas, ko mÄs norÄdÄ«jÄm paÅ”Ä sÄkumÄ, iestatot Travis CI vides mainÄ«gos.
OtrÄ rinda tieÅ”i sÄk analÄ«zi. Karogs -j iestata analÄ«zes pavedienu skaitu, karodziÅÅ” -l norÄda licenci, karogu -o definÄ failu žurnÄlu izvadÄ«Å”anai un karogu - DisableLicenseExpirationCheck nepiecieÅ”ams izmÄÄ£inÄjuma versijÄm, jo āāpÄc noklusÄjuma pvs-studio-analizators brÄ«dinÄs lietotÄju, ka drÄ«z beigsies licences derÄ«guma termiÅÅ”. Lai tas nenotiktu, varat norÄdÄ«t Å”o karogu.
ŽurnÄla failÄ ir neapstrÄdÄta izvade, ko nevar nolasÄ«t bez konvertÄÅ”anas, tÄpÄc vispirms fails ir jÄpadara lasÄms. IzlaidÄ«sim baļķus cauri plog pÄrveidotÄjs, un izvade ir html fails.
Å ajÄ piemÄrÄ es nolÄmu nosÅ«tÄ«t pÄrskatus pa pastu, izmantojot komandu sÅ«tÄ«t e-pastu.
#/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;
Tagad ir pienÄcis laiks virzÄ«t izmaiÅas git repozitorijÄ, un pÄc tam Travis CI automÄtiski palaidÄ«s bÅ«vÄjumu. NoklikŔķiniet uz āppssppā, lai pÄrietu uz bÅ«vÄÅ”anas pÄrskatiem:
MÄs redzÄsim paÅ”reizÄjÄs versijas pÄrskatu:
Ja bÅ«vÄÅ”ana tiks veiksmÄ«gi pabeigta, mÄs saÅemsim e-pastu ar statiskÄs analÄ«zes rezultÄtiem. Protams, pasta sÅ«tÄ«Å”ana nav vienÄ«gais veids, kÄ saÅemt ziÅojumu. Varat izvÄlÄties jebkuru ievieÅ”anas metodi. Bet ir svarÄ«gi atcerÄties, ka pÄc bÅ«vÄÅ”anas pabeigÅ”anas nebÅ«s iespÄjams piekļūt virtuÄlÄs maŔīnas failiem.
Kļūdu kopsavilkums
MÄs esam veiksmÄ«gi pabeiguÅ”i grÅ«tÄko daļu. Tagad pÄrliecinÄsimies, ka visas mÅ«su pÅ«les ir tÄ vÄrtas. ApskatÄ«sim dažus interesantus punktus no statiskÄs analÄ«zes ziÅojuma, kas man atnÄca pa pastu (ne velti es to norÄdÄ«ju).
PVS-Studio brÄ«dinÄjums: V597 Kompilators varÄtu izdzÄst funkcijas āmemsetā izsaukumu, kas tiek izmantots, lai izskalotu āsummasā buferi. Lai dzÄstu privÄtos datus, ir jÄizmanto funkcija RtlSecureZeroMemory(). sha1.cpp 325
Å is koda fragments atrodas droÅ”Äs jaukÅ”anas modulÄ«, taÄu tajÄ ir nopietns droŔības trÅ«kums (CWE-14). ApskatÄ«sim montÄžas sarakstu, kas tiek Ä£enerÄts, sastÄdot atkļūdoÅ”anas versiju:
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Viss ir kÄrtÄ«bÄ un darbojas memeset tiek izpildÄ«ts, tÄdÄjÄdi pÄrrakstot svarÄ«gus datus RAM, tomÄr vÄl nepriecÄjieties. ApskatÄ«sim izlaiduma versijas komplektÄcijas sarakstu ar optimizÄciju:
KÄ redzams no saraksta, kompilators ignorÄja zvanu memeset. Tas ir saistÄ«ts ar faktu, ka funkcijÄ sha1 pÄc zvana memeset vairs nav atsauces uz struktÅ«ru ctx. TÄpÄc kompilators neredz jÄgu tÄrÄt procesora laiku, pÄrrakstot atmiÅu, kas turpmÄk netiek izmantota. To var novÄrst, izmantojot funkciju RtlSecureZeroMemory vai lÄ«dzÄ«gi viÅai.
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);
}
}
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);
}
}
Cits scenÄrijs. Aiz Å”iem liekajiem apstÄkļiem slÄpjas kÄda veida kļūda. VarbÅ«t viÅi nepÄrbaudÄ«ja, kas bija vajadzÄ«gs.
V501 Ir identiskas apakŔizteiksmes '!Memory::IsValidAddress(psmfData)' pa kreisi un pa labi no '||' operators. scePsmf.cpp 703
PievÄrsiet uzmanÄ«bu Äekam iekÅ”pusÄ if. Vai jums neliekas dÄ«vaini, ka mÄs pÄrbaudÄm, vai adrese ir derÄ«ga? psmfData, divreiz vairÄk? TÄpÄc man tas Ŕķiet dÄ«vaini... PatiesÄ«bÄ Å”Ä«, protams, ir drukas kļūda, un doma bija pÄrbaudÄ«t abus ievades parametrus.
Å Ä« kļūda atrodas mapÄ ext, tÄtad projektam Ä«sti neatbilstoÅ”i, bet kļūda tika atrasta pirms es to pamanÄ«ju, tÄpÄc nolÄmu to atstÄt. Galu galÄ Å”is raksts nav par kļūdu pÄrskatÄ«Å”anu, bet gan par integrÄciju ar Travis CI, un netika veikta analizatora konfigurÄcija.
MainÄ«gs izmÄrs tiek inicializÄts ar konstanti, taÄu tas netiek izmantots kodÄ vispÄr, lÄ«dz pat operatoram if, kas, protams, dod nepatiess pÄrbaudot nosacÄ«jumus, jo, kÄ mÄs atceramies, izmÄrs vienÄds ar nulli. ArÄ« turpmÄkajÄm pÄrbaudÄm nav jÄgas.
AcÄ«mredzot koda fragmenta autors aizmirsa pÄrrakstÄ«t mainÄ«go izmÄrs pirms tam.
apstÄties
Å eit mÄs, iespÄjams, beigsim ar kļūdÄm. Å Ä« raksta mÄrÄ·is ir demonstrÄt PVS-Studio darbu kopÄ ar Travis CI, nevis analizÄt projektu pÄc iespÄjas rÅ«pÄ«gÄk. Ja vÄlaties lielÄkas un skaistÄkas kļūdas, vienmÄr varat par tÄm apbrÄ«not Å”eit :).
SecinÄjums
Izmantojot tÄ«mekļa pakalpojumus projektu veidoÅ”anai kopÄ ar pakÄpeniskas analÄ«zes praksi, jÅ«s varat atrast daudzas problÄmas uzreiz pÄc koda apvienoÅ”anas. TomÄr ar vienu bÅ«vÄjumu var nepietikt, tÄpÄc testÄÅ”anas iestatÄ«Å”ana kopÄ ar statisko analÄ«zi ievÄrojami uzlabos koda kvalitÄti.