Travis CI er dreifð vefþjónusta til að smíða og prófa hugbúnað sem notar GitHub sem frumkóðahýsingu. Til viðbótar við ofangreindar rekstrarsviðsmyndir geturðu bætt við þínum eigin þökk sé víðtækum stillingarvalkostum. Í þessari grein munum við stilla Travis CI til að vinna með PVS-Studio með því að nota PPSSPP kóða dæmið.
Inngangur
Uppsetning Travis CI
Við munum þurfa geymslu á GitHub, þar sem verkefnið sem við þurfum er staðsett, sem og lykil fyrir PVS-Studio (þú getur fengið
Við skulum fara á síðuna
Fyrir prófið gaf ég PPSSPP.
Við virkum geymsluna sem við viljum safna:
Í augnablikinu getur Travis CI ekki byggt verkefnið okkar vegna þess að það eru engar leiðbeiningar um byggingu. Svo það er kominn tími á uppsetningu.
Við greininguna munu sumar breytur nýtast okkur, til dæmis lykillinn fyrir PVS-Studio, sem óæskilegt væri að tilgreina í stillingarskránni. Svo skulum við bæta við umhverfisbreytum með því að nota byggingarstillingarnar í Travis CI:
Við munum þurfa:
- PVS_USERNAME - notendanafn
- PVS_KEY - lykill
- MAIL_USER - tölvupóstur sem verður notaður til að senda skýrsluna
- MAIL_PASSWORD - lykilorð fyrir tölvupóst
Síðustu tveir eru valfrjálsir. Þetta verður notað til að senda niðurstöður í pósti. Ef þú vilt dreifa skýrslunni á annan hátt þarftu ekki að tilgreina þær.
Þannig að við höfum bætt við umhverfisbreytunum sem við þurfum:
Nú skulum við búa til skrá .travis.yml og setja það í rót verkefnisins. PPSSPP var þegar með stillingarskrá fyrir Travis CI, hún var hins vegar of stór og algjörlega óhentug fyrir dæmið, svo við urðum að einfalda hana til muna og skilja aðeins eftir grunnþættina.
Í fyrsta lagi skulum við gefa til kynna tungumálið, útgáfu Ubuntu Linux sem við viljum nota í sýndarvélinni og nauðsynlega pakka fyrir smíðina:
language: cpp
dist: xenial
addons:
apt:
update: true
packages:
- ant
- aria2
- build-essential
- cmake
- libgl1-mesa-dev
- libglu1-mesa-dev
- libsdl2-dev
- pv
- sendemail
- software-properties-common
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'ppa:ubuntu-sdk-team/ppa'
Allir pakkar sem eru skráðir eru eingöngu nauðsynlegir fyrir PPSSPP.
Nú tilgreinum við samsetningarfylki:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Aðeins meira um kaflann fylki. Í Travis CI eru tvær leiðir til að búa til byggingarvalkosti: sú fyrsta er að tilgreina lista yfir þýðendur, stýrikerfisgerðir, umhverfisbreytur o.s.frv., eftir það myndast fylki með öllum mögulegum samsetningum; annað er skýr vísbending um fylkið. Auðvitað geturðu sameinað þessar tvær aðferðir og bætt við einstöku tilviki, eða þvert á móti, útilokað það með því að nota hlutann útiloka. Þú getur lesið meira um þetta í
Það eina sem er eftir er að koma með verksértækar samsetningarleiðbeiningar:
before_install:
- travis_retry bash .travis.sh travis_before_install
install:
- travis_retry bash .travis.sh travis_install
script:
- bash .travis.sh travis_script
after_success:
- bash .travis.sh travis_after_success
Travis CI gerir þér kleift að bæta við þínum eigin skipunum fyrir mismunandi stig í lífi sýndarvélar. kafla before_install keyrt áður en pakka er sett upp. Þá setja, sem fylgir uppsetningu pakka af listanum addons.aptsem við bentum á hér að ofan. Þingið sjálft fer fram í handrit. Ef allt gekk vel, þá finnum við okkur sjálf eftir_árangur (það er í þessum hluta sem við munum keyra kyrrstöðugreiningu). Þetta eru ekki öll skrefin sem hægt er að breyta, ef þú þarft meira, þá ættirðu að líta inn
Til að auðvelda lestur voru skipanirnar settar í sérstakt handrit .travis.sh, sem er sett við verkrót.
Svo við höfum eftirfarandi skrá .travis.yml:
language: cpp
dist: xenial
addons:
apt:
update: true
packages:
- ant
- aria2
- build-essential
- cmake
- libgl1-mesa-dev
- libglu1-mesa-dev
- libsdl2-dev
- pv
- sendemail
- software-properties-common
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'ppa:ubuntu-sdk-team/ppa'
matrix:
include:
- os: linux
compiler: "gcc"
env: PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
before_install:
- travis_retry bash .travis.sh travis_before_install
install:
- travis_retry bash .travis.sh travis_install
script:
- bash .travis.sh travis_script
after_success:
- bash .travis.sh travis_after_success
Áður en pakkarnir eru settir upp munum við uppfæra undireiningarnar. Þetta er nauðsynlegt til að byggja upp PPSSPP. Við skulum bæta fyrstu aðgerðinni við .travis.sh (athugið framlenginguna):
travis_before_install() {
git submodule update --init --recursive
}
Nú komum við beint að því að setja upp sjálfvirka ræsingu PVS-Studio í Travis CI. Fyrst þurfum við að setja upp PVS-Studio pakkann á kerfinu:
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
}
Í upphafi fallsins travis_install við setjum upp þýðendur sem við þurfum með því að nota umhverfisbreytur. Þá ef breyt $PVS_ANALYZE verðmæti verslana Já (við bentum á það í kaflanum env við uppsetningu byggðarfylkis), setjum við upp pakkann pvs-stúdíó. Auk þessa eru pakkar einnig tilgreindir libio-socket-ssl-perl и libnet-ssleay-perlÞær eru hins vegar nauðsynlegar til að senda niðurstöður, svo þær eru ekki nauðsynlegar ef þú hefur valið aðra aðferð til að koma skýrslunni til skila.
Virka niðurhal_útdráttur hleður niður og pakkar upp tilgreindu skjalasafni:
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
Það er kominn tími til að setja verkefnið saman. Þetta gerist í kaflanum handrit:
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
}
Reyndar er þetta einfölduð upprunaleg uppsetning, nema þessar línur:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Í þessum hluta kóða sem við setjum fyrir cmgerð fána til að flytja út safnskipanir. Þetta er nauðsynlegt fyrir kyrrstöðugreiningartæki. Þú getur lesið meira um þetta í greininni “
Ef samkoman heppnaðist vel, þá komumst við að eftir_árangur, þar sem við framkvæmum kyrrstöðugreiningu:
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
}
Við skulum skoða nánar eftirfarandi línur:
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
Fyrsta línan býr til leyfisskrá úr notandanafninu og lyklinum sem við tilgreindum í upphafi þegar Travis CI umhverfisbreyturnar voru settar upp.
Önnur línan byrjar greininguna beint. Fáni -j setur fjölda þráða til greiningar, flaggi -l gefur til kynna leyfi, fána -o skilgreinir skrána til að gefa út logs og fánann -disableLicense ExpirationCheck krafist fyrir prufuútgáfur, þar sem sjálfgefið er pvs-stúdíó-greiningartæki mun vara notandann við því að leyfið sé að renna út. Til að koma í veg fyrir að þetta gerist geturðu tilgreint þennan fána.
Notkunarskráin inniheldur hrátt úttak sem ekki er hægt að lesa án umbreytingar, svo þú verður fyrst að gera skrána læsilega. Við skulum renna stokkunum í gegn plog-breytir, og úttakið er html skrá.
Í þessu dæmi ákvað ég að senda skýrslur í pósti með skipuninni senda tölvupóst.
Fyrir vikið fengum við eftirfarandi skrá .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;
Nú er kominn tími til að ýta undir breytingar á git geymslunni, eftir það mun Travis CI keyra bygginguna sjálfkrafa. Smelltu á „ppsspp“ til að fara í byggingarskýrslurnar:
Við munum sjá yfirlit yfir núverandi byggingu:
Ef smíði er lokið, munum við fá tölvupóst með niðurstöðum kyrrstöðugreiningarinnar. Auðvitað er póstsending ekki eina leiðin til að fá skýrslu. Þú getur valið hvaða útfærsluaðferð sem er. En það er mikilvægt að muna að eftir að smíði er lokið verður ekki hægt að nálgast sýndarvélaskrárnar.
Villusamantekt
Við höfum lokið erfiðasta hlutanum. Nú skulum við ganga úr skugga um að öll viðleitni okkar sé þess virði. Við skulum skoða nokkra áhugaverða punkta úr kyrrstöðugreiningarskýrslunni sem barst mér í pósti (það var ekki fyrir ekkert sem ég gaf til kynna).
Hættuleg hagræðing
void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) );
}
PVS-Stúdíó viðvörun:
Þetta stykki af kóða er staðsett í öruggu hashing-einingunni, en hann inniheldur hins vegar alvarlegan öryggisgalla (
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Allt er í röð og reglu og virkni memeset er keyrt, og skrifar þar með yfir mikilvæg gögn í vinnsluminni, þó ekki fagna enn sem komið er. Við skulum skoða samsetningarskráningu útgáfu útgáfunnar með hagræðingu:
; 354 :
; 355 : memset( sum, 0, sizeof( sum ) );
; 356 :}
Eins og sjá má á skráningunni hunsaði þýðandinn símtalið memeset. Þetta er vegna þess að í aðgerðinni sha1 eftir símtalið memeset ekki lengur tilvísun í uppbyggingu ctx. Þess vegna sér þýðandinn engan tilgang í að eyða tíma örgjörva í að skrifa yfir minni sem ekki er notað í framtíðinni. Þú getur lagað þetta með því að nota aðgerðina RtlSecureZeroMemory eða
Rétt:
void sha1( unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
RtlSecureZeroMemory(&ctx, sizeof( sha1_context ) );
}
Óþarfa samanburður
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-Stúdíó viðvörun:
Gefðu gaum að annarri greininni fyrir það fyrsta if. Kóðinn verður aðeins keyrður að öllum skilyrðum uppfylltum leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || hægrivol < 0 mun reynast rangt. Þess vegna fáum við eftirfarandi fullyrðingar, sem eiga við um hina greinina: leftvol <= 0xFFFF, rightvol <= 0xFFFF, vinstrivoli >= 0 и rightvol >= 0. Taktu eftir síðustu tveimur fullyrðingunum. Er skynsamlegt að athuga hvað er nauðsynlegt skilyrði fyrir framkvæmd þessa kóða?
Svo við getum örugglega fjarlægt þessar skilyrtu yfirlýsingar:
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);
}
}
Önnur atburðarás. Það er einhvers konar villa falin á bak við þessi óþarfa skilyrði. Kannski athugaðu þeir ekki hvað var krafist.
Ctrl+C Ctrl+V slær til baka
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfData) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Gefðu gaum að ávísuninni inni if. Finnst þér ekki skrítið að við athugum hvort heimilisfangið sé gilt? psmfGögn, tvöfalt meira? Svo þetta finnst mér skrítið... Reyndar er þetta auðvitað innsláttarvilla og hugmyndin var að athuga báðar innsláttarfæribreyturnar.
Réttur valkostur:
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfStruct) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Gleymd breyta
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-Stúdíó viðvörun:
Þessi villa er staðsett í möppunni EXT, svo ekki í raun við verkefnið, en villan fannst áður en ég tók eftir því, svo ég ákvað að yfirgefa hana. Þegar öllu er á botninn hvolft snýst þessi grein ekki um að skoða villur, heldur um samþættingu við Travis CI, og engin uppsetning á greiningartækinu var framkvæmd.
Breytilegt stærð er frumstillt með fasta, hins vegar er hann alls ekki notaður í kóðanum, alveg niður til rekstraraðilans if, sem auðvitað gefur rangar við að athuga skilyrðin, því eins og við munum, stærð jafnt og núll. Síðari athuganir hafa heldur engan tilgang.
Svo virðist sem höfundur kóðabrotsins hafi gleymt að skrifa yfir breytuna stærð fyrir það.
Hætta
Þetta er þar sem við munum líklega enda með mistökin. Tilgangur þessarar greinar er að sýna fram á vinnu PVS-Studio ásamt Travis CI, en ekki að greina verkefnið eins ítarlega og hægt er. Ef þú vilt stærri og fallegri mistök geturðu alltaf dáðst að þeim
Ályktun
Með því að nota vefþjónustur til að byggja upp verkefni ásamt því að æfa stigvaxandi greiningu geturðu fundið mörg vandamál strax eftir sameiningu kóða. Hins vegar gæti ein bygging ekki verið nóg, svo að setja upp próf ásamt kyrrstöðugreiningu mun bæta gæði kóðans verulega.
gagnlegir krækjur
Ef þú vilt deila þessari grein með enskumælandi áhorfendum, vinsamlegast notaðu þýðingartengilinn: Maxim Zvyagintsev.
Heimild: www.habr.com