Travis CI ni huduma ya tovuti iliyosambazwa ya kuunda na kujaribu programu inayotumia GitHub kama upangishaji wa msimbo wa chanzo. Mbali na matukio ya uendeshaji hapo juu, unaweza kuongeza shukrani yako mwenyewe kwa chaguzi nyingi za usanidi. Katika makala hii tutasanidi Travis CI kufanya kazi na PVS-Studio kwa kutumia mfano wa msimbo wa PPSSPP.
Utangulizi
Kuanzisha Travis CI
Tutahitaji hazina kwenye GitHub, ambapo mradi tunaohitaji iko, pamoja na ufunguo wa PVS-Studio (unaweza kupata
Twende kwenye tovuti
Kwa mtihani, niligawa PPSSPP.
Tunawasha hazina ambayo tunataka kukusanya:
Kwa sasa, Travis CI haiwezi kujenga mradi wetu kwa sababu hakuna maagizo ya kujenga. Kwa hivyo ni wakati wa usanidi.
Wakati wa uchanganuzi, vigeu vingine vitatufaa, kwa mfano, ufunguo wa PVS-Studio, ambayo itakuwa mbaya kutaja kwenye faili ya usanidi. Kwa hivyo wacha tuongeze anuwai za mazingira kwa kutumia mipangilio ya ujenzi katika Travis CI:
Tutahitaji:
- PVS_USERNAME - jina la mtumiaji
- PVS_KEY - ufunguo
- MAIL_USER - barua pepe ambayo itatumika kutuma ripoti
- MAIL_PASSWORD - nenosiri la barua pepe
Mbili za mwisho ni za hiari. Hizi zitatumika kutuma matokeo kwa barua. Ikiwa unataka kusambaza ripoti kwa njia nyingine, huna haja ya kuwaonyesha.
Kwa hivyo, tumeongeza anuwai za mazingira tunazohitaji:
Sasa hebu tuunde faili .travis.yml na kuiweka kwenye mzizi wa mradi. PPSSPP tayari ilikuwa na faili ya usanidi kwa Travis CI, hata hivyo, ilikuwa kubwa sana na haifai kabisa kwa mfano, kwa hiyo tulipaswa kurahisisha sana na kuacha vipengele vya msingi tu.
Kwanza, hebu tuonyeshe lugha, toleo la Ubuntu Linux ambalo tunataka kutumia kwenye mashine ya kawaida, na vifurushi muhimu vya ujenzi:
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'
Vifurushi vyote vilivyoorodheshwa vinahitajika kwa ajili ya PPSSPP pekee.
Sasa tunaonyesha matrix ya kusanyiko:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Zaidi kidogo juu ya sehemu hiyo tumbo. Katika Travis CI, kuna njia mbili za kuunda chaguzi za kujenga: kwanza ni kutaja orodha ya wakusanyaji, aina za mfumo wa uendeshaji, vigezo vya mazingira, nk, baada ya hapo matrix ya mchanganyiko wote iwezekanavyo hutolewa; pili ni dalili ya wazi ya tumbo. Kwa kweli, unaweza kuchanganya njia hizi mbili na kuongeza kesi ya kipekee, au, kinyume chake, kuitenga kwa kutumia sehemu hiyo. kuwatenga. Unaweza kusoma zaidi kuhusu hili katika
Kilichobaki ni kutoa maagizo mahususi ya mkutano wa mradi:
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 hukuruhusu kuongeza amri zako mwenyewe kwa hatua mbalimbali za maisha ya mashine pepe. Sehemu kabla_kusakinisha kutekelezwa kabla ya kusakinisha vifurushi. Kisha kufunga, ambayo inafuata usakinishaji wa vifurushi kutoka kwenye orodha addons.apttuliyoonyesha hapo juu. Mkutano yenyewe unafanyika ndani Muswada. Ikiwa kila kitu kilikwenda vizuri, basi tunajikuta ndani baada_ya_mafanikio (ni katika sehemu hii tutaendesha uchambuzi tuli). Hizi sio hatua zote zinazoweza kurekebishwa, ikiwa unahitaji zaidi, basi unapaswa kuangalia ndani
Kwa urahisi wa kusoma, amri ziliwekwa kwenye hati tofauti .travis.sh, ambayo imewekwa kwenye mzizi wa mradi.
Kwa hivyo tunayo faili ifuatayo .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
Kabla ya kusakinisha vifurushi, tutasasisha submodule. Hii inahitajika ili kujenga PPSSPP. Hebu tuongeze kitendakazi cha kwanza kwa .travis.sh (kumbuka kiendelezi):
travis_before_install() {
git submodule update --init --recursive
}
Sasa tunakuja moja kwa moja kusanidi uzinduzi wa kiotomatiki wa PVS-Studio katika Travis CI. Kwanza tunahitaji kusanikisha kifurushi cha PVS-Studio kwenye mfumo:
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
}
Mwanzoni mwa kazi travis_install sisi kufunga compilers tunahitaji kutumia vigezo mazingira. Kisha ikiwa kutofautiana $PVS_ANALYZE thamani ya maduka Ndiyo (Tuliionyesha katika sehemu env wakati wa usanidi wa matrix ya kujenga), tunaweka kifurushi pvs-studio. Kwa kuongeza hii, vifurushi pia vinaonyeshwa libio-tundu-ssl-perl ΠΈ libnet-ssleay-perl, hata hivyo, zinahitajika kwa matokeo ya utumaji barua, kwa hivyo sio lazima ikiwa umechagua njia nyingine ya kuwasilisha ripoti yako.
Kazi pakua_dondoo kupakua na kufungua kumbukumbu maalum:
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
Ni wakati wa kuweka mradi pamoja. Hii hutokea katika sehemu Muswada:
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
}
Kwa kweli, huu ni usanidi wa asili uliorahisishwa, isipokuwa kwa mistari hii:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Katika sehemu hii ya kanuni sisi kuweka kwa cmke bendera ya kusafirisha amri za mkusanyiko. Hii ni muhimu kwa kichanganuzi cha nambari tuli. Unaweza kusoma zaidi juu ya hii katika makala "
Ikiwa kusanyiko lilifanikiwa, basi tutafika baada_ya_mafanikio, ambapo tunafanya uchambuzi tuli:
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
}
Wacha tuangalie kwa karibu mistari ifuatayo:
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
Mstari wa kwanza hutengeneza faili ya leseni kutoka kwa jina la mtumiaji na ufunguo ambao tulitaja mwanzoni kabisa wakati wa kusanidi anuwai ya mazingira ya Travis CI.
Mstari wa pili unaanza uchambuzi moja kwa moja. Bendera -j huweka idadi ya nyuzi kwa uchambuzi, bendera -l inaonyesha leseni, bendera -o inafafanua faili kwa magogo ya kutoa, na bendera -lemazaUkagua wa KuishaLeseniKuisha inahitajika kwa matoleo ya majaribio, kwani kwa chaguo-msingi pvs-studio-analyzer itamwonya mtumiaji kuwa leseni inakaribia kuisha. Ili kuzuia hili kutokea, unaweza kubainisha bendera hii.
Faili ya kumbukumbu ina pato ghafi ambalo haliwezi kusomwa bila ubadilishaji, kwa hivyo lazima kwanza ufanye faili isomeke. Wacha tupitishe magogo kibadilishaji cha plagi, na matokeo ni faili ya html.
Katika mfano huu, niliamua kutuma ripoti kwa barua kwa kutumia amri kutuma barua pepe.
Kama matokeo, tulipata faili ifuatayo .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;
Sasa ni wakati wa kusukuma mabadiliko kwenye hazina ya git, baada ya hapo Travis CI itaendesha kiotomatiki ujenzi. Bofya kwenye "ppsspp" ili kwenda kwenye ripoti za muundo:
Tutaona muhtasari wa muundo wa sasa:
Ikiwa ujenzi umekamilika kwa ufanisi, tutapokea barua pepe na matokeo ya uchambuzi wa tuli. Bila shaka, kutuma barua sio njia pekee ya kupokea ripoti. Unaweza kuchagua njia yoyote ya utekelezaji. Lakini ni muhimu kukumbuka kuwa baada ya ujenzi kukamilika, haitawezekana kufikia faili za mashine za kawaida.
Muhtasari wa makosa
Tumefanikiwa kumaliza sehemu ngumu zaidi. Sasa tuhakikishe kwamba juhudi zetu zote zinastahili. Wacha tuangalie vidokezo vya kupendeza kutoka kwa ripoti ya uchambuzi tuli ambayo ilinijia kwa barua (haikuwa bure kwamba niliionyesha).
Uboreshaji hatari
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 ) );
}
Onyo la PVS-Studio:
Sehemu hii ya msimbo iko kwenye moduli salama ya hashing, hata hivyo, ina dosari kubwa ya usalama (
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Kila kitu kiko katika mpangilio na kazi memeset inatekelezwa, na hivyo kufuta data muhimu katika RAM, hata hivyo, usifurahi bado. Wacha tuangalie uorodheshaji wa kusanyiko wa toleo la Toleo na uboreshaji:
; 354 :
; 355 : memset( sum, 0, sizeof( sum ) );
; 356 :}
Kama inavyoonekana kutoka kwa uorodheshaji, mkusanyaji alipuuza simu hiyo memeset. Hii ni kutokana na ukweli kwamba katika kazi sha1 baada ya simu memeset hakuna kumbukumbu tena kwa muundo ctx. Kwa hivyo, mkusanyaji haoni maana ya kupoteza wakati wa kichakataji kubandika kumbukumbu ambayo haitatumika katika siku zijazo. Unaweza kurekebisha hii kwa kutumia kazi RtlSecureZeroMemory au
Haki:
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 ) );
}
Ulinganisho usio wa lazima
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);
}
}
Onyo la PVS-Studio:
Zingatia tawi lingine kwa la kwanza if. Nambari itatekelezwa tu ikiwa hali zote leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || sauti ya kulia <0 itageuka kuwa ya uwongo. Kwa hivyo, tunapata taarifa zifuatazo, ambazo zitakuwa kweli kwa tawi lingine: leftvol <= 0xFFFF, rightvol <= 0xFFFF, leftvol >= 0 ΠΈ rightvol>= 0. Angalia kauli mbili za mwisho. Inaleta maana kuangalia ni hali gani muhimu kwa utekelezaji wa kipande hiki cha nambari?
Kwa hivyo tunaweza kuondoa taarifa hizi za masharti kwa usalama:
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);
}
}
Hali nyingine. Kuna aina fulani ya hitilafu iliyofichwa nyuma ya hali hizi zisizohitajika. Labda hawakuangalia kile kilichohitajika.
Ctrl+C Ctrl+V Hupiga Nyuma
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfData) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Makini na hundi ndani if. Je, huoni kuwa ni jambo la kushangaza kwamba tunaangalia ikiwa anwani ni halali? psmfData, mara mbili zaidi? Kwa hiyo hii inaonekana ya ajabu kwangu ... Kwa kweli, hii ni, bila shaka, typo, na wazo lilikuwa kuangalia vigezo vyote vya pembejeo.
Chaguo sahihi:
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfStruct) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Tofauti iliyosahaulika
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");
}
....
}
Onyo la PVS-Studio:
Hitilafu hii iko kwenye folda ext, kwa hivyo sio muhimu sana kwa mradi huo, lakini mdudu alipatikana kabla sijaiona, kwa hivyo niliamua kuiacha. Baada ya yote, nakala hii sio juu ya kukagua makosa, lakini juu ya kuunganishwa na Travis CI, na hakuna usanidi wa kichambuzi ulifanywa.
Inaweza kubadilika kawaida inaanzishwa na mara kwa mara, hata hivyo, haitumiwi kabisa katika msimbo, hadi kwa operator if, ambayo, bila shaka, inatoa uongo wakati wa kuangalia hali, kwa sababu, kama tunavyokumbuka, kawaida sawa na sifuri. Ukaguzi unaofuata pia hauna maana.
Inavyoonekana, mwandishi wa kipande cha msimbo alisahau kufuta kutofautisha kawaida kabla ya hapo.
Kuacha
Hapa ndipo pengine tutamalizia na makosa. Madhumuni ya kifungu hiki ni kuonyesha kazi ya PVS-Studio pamoja na Travis CI, na sio kuchambua mradi huo kwa undani iwezekanavyo. Ikiwa unataka makosa makubwa na mazuri zaidi, unaweza kuwavutia kila wakati
Hitimisho
Kutumia huduma za wavuti kujenga miradi pamoja na mazoezi ya uchanganuzi wa nyongeza hukuruhusu kupata shida nyingi mara baada ya kuunganisha nambari. Walakini, muundo mmoja unaweza kuwa hautoshi, kwa hivyo kusanidi majaribio pamoja na uchanganuzi tuli kutaboresha sana ubora wa nambari.
Viungo muhimu
Ikiwa ungependa kushiriki makala hii na hadhira inayozungumza Kiingereza, tafadhali tumia kiungo cha kutafsiri: Maxim Zvyagintsev.
Chanzo: mapenzi.com