ProHoster > Օրագիր > Վարչակազմը > Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Travis CI-ն բաշխված վեբ ծառայություն է ծրագրային ապահովման կառուցման և փորձարկման համար, որն օգտագործում է GitHub-ը որպես սկզբնական կոդի հոստինգ: Բացի վերը նշված գործառնական սցենարներից, դուք կարող եք ավելացնել ձեր սեփականը` շնորհիվ կազմաձևման լայն ընտրանքների: Այս հոդվածում մենք կկարգավորենք Travis CI-ն PVS-Studio-ի հետ աշխատելու համար՝ օգտագործելով PPSSPP կոդի օրինակը:
Ներածություն
Թրևիս CI ծրագրային ապահովման կառուցման և փորձարկման վեբ ծառայություն է: Այն սովորաբար օգտագործվում է շարունակական ինտեգրման պրակտիկայի հետ համատեղ:
PPSSPP - PSP խաղային կոնսոլի էմուլատոր: Ծրագիրը կարող է ընդօրինակել Sony PSP-ի համար նախատեսված սկավառակի պատկերներից ցանկացած խաղի մեկնարկը: Ծրագիրը թողարկվել է 1 թվականի նոյեմբերի 2012-ին։ PPSSPP-ը լիցենզավորված է GPL v2-ի ներքո: Յուրաքանչյուրը կարող է բարելավումներ կատարել նախագծի սկզբնական կոդը.
PVS- ստուդիա — ստատիկ կոդի անալիզատոր՝ ծրագրային կոդում սխալների և հնարավոր խոցելիությունների որոնման համար: Այս հոդվածում, փոփոխության համար, մենք կգործարկենք PVS-Studio-ն ոչ թե տեղական մշակողի մեքենայի վրա, այլ ամպի մեջ և կփնտրենք սխալներ PPSSPP-ում:
Եկեք գնանք կայք Թրևիս CI. Ձեր GitHub հաշիվն օգտագործելուց թույլտվությունից հետո մենք կտեսնենք պահեստների ցանկը.
Փորձարկման համար ես պատառաքաղեցի PPSSPP:
Մենք ակտիվացնում ենք պահեստը, որը ցանկանում ենք հավաքել.
Այս պահին Travis CI-ն չի կարող կառուցել մեր նախագիծը, քանի որ շինարարության հրահանգներ չկան: Այսպիսով, ժամանակն է կոնֆիգուրացիայի համար:
Վերլուծության ընթացքում որոշ փոփոխականներ օգտակար կլինեն մեզ համար, օրինակ՝ PVS-Studio-ի բանալին, որն անցանկալի կլիներ նշել կոնֆիգուրացիայի ֆայլում: Այսպիսով, եկեք ավելացնենք շրջակա միջավայրի փոփոխականներ՝ օգտագործելով Travis CI-ի կառուցման կարգավորումները.
Մենք պետք է.
PVS_USERNAME - օգտվողի անուն
PVS_KEY - բանալի
MAIL_USER - էլփոստ, որը կօգտագործվի զեկույցն ուղարկելու համար
MAIL_PASSWORD - էլփոստի գաղտնաբառ
Վերջին երկուսը կամընտիր են: Դրանք կօգտագործվեն արդյունքները փոստով ուղարկելու համար: Եթե ցանկանում եք հաշվետվությունը տարածել այլ կերպ, ապա ձեզ հարկավոր չէ դրանք նշել:
Այսպիսով, մենք ավելացրել ենք մեզ անհրաժեշտ շրջակա միջավայրի փոփոխականները.
Հիմա եկեք ստեղծենք ֆայլ .travis.yml և տեղադրեք այն նախագծի արմատում: PPSSPP-ն արդեն ուներ կազմաձևման ֆայլ Travis CI-ի համար, այնուամենայնիվ, այն չափազանց մեծ էր և բացարձակապես ոչ պիտանի օրինակի համար, այնպես որ մենք ստիպված էինք մեծապես պարզեցնել այն և թողնել միայն հիմնական տարրերը:
Նախ, եկեք նշենք լեզուն, Ubuntu Linux-ի տարբերակը, որը մենք ցանկանում ենք օգտագործել վիրտուալ մեքենայում, և կառուցման համար անհրաժեշտ փաթեթները.
Բոլոր փաթեթները, որոնք նշված են, անհրաժեշտ են բացառապես PPSSPP-ի համար:
Այժմ մենք նշում ենք հավաքման մատրիցը.
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Մի փոքր ավելին բաժնի մասին matrix. Travis CI-ում կառուցման տարբերակներ ստեղծելու երկու եղանակ կա. առաջինը՝ նշել կոմպիլյատորների ցանկը, օպերացիոն համակարգերի տեսակները, շրջակա միջավայրի փոփոխականները և այլն, որից հետո ստեղծվում է բոլոր հնարավոր համակցությունների մատրիցը; երկրորդը մատրիցայի բացահայտ նշումն է: Իհարկե, դուք կարող եք համատեղել այս երկու մոտեցումները և ավելացնել եզակի դեպք, կամ, ընդհակառակը, բացառել այն՝ օգտագործելով բաժինը. բացառել. Այս մասին ավելին կարող եք կարդալ այստեղ Travis CI փաստաթղթերը.
Մնում է միայն տրամադրել նախագծին հատուկ հավաքման հրահանգներ.
Travis CI-ն թույլ է տալիս ավելացնել ձեր սեփական հրամանները վիրտուալ մեքենայի կյանքի տարբեր փուլերի համար: Բաժին before_install կատարված փաթեթները տեղադրելուց առաջ: Հետո տեղադրել, որը հետևում է ցանկից փաթեթների տեղադրմանը addons.aptորը մենք նշեցինք վերևում։ Ժողովն ինքնին տեղի է ունենում ձեռագիր. Եթե ամեն ինչ լավ է անցել, ուրեմն մենք հայտնվում ենք մեր մեջ հետո_հաջողություն (այս բաժնում է, որ մենք կկատարենք ստատիկ վերլուծություն): Սրանք բոլոր քայլերը չեն, որոնք կարելի է փոփոխել, եթե ձեզ ավելին է պետք, ապա պետք է նայեք Travis CI փաստաթղթերը.
Ընթերցանության հեշտության համար հրամանները տեղադրվեցին առանձին սցենարով .travis.sh, որը տեղադրված է նախագծի արմատում:
Նախքան փաթեթները տեղադրելը, մենք կթարմացնենք ենթամոդուլները։ Սա անհրաժեշտ է PPSSPP կառուցելու համար: Ավելացնենք առաջին ֆունկցիան .travis.sh (նկատի ունեցեք ընդլայնումը):
Այժմ մենք ուղղակիորեն գալիս ենք կարգավորելու PVS-Studio-ի ավտոմատ գործարկումը Travis CI-ում: Նախ պետք է համակարգում տեղադրենք PVS-Studio փաթեթը.
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_install մենք տեղադրում ենք մեզ անհրաժեշտ կոմպիլյատորները՝ օգտագործելով շրջակա միջավայրի փոփոխականները: Ապա եթե փոփոխականը $ Pvs_analyze պահպանում է արժեքը այո (մենք դա նշել ենք բաժնում նախանձ կառուցման մատրիցայի կազմաձևման ժամանակ), մենք տեղադրում ենք փաթեթը pvs-ստուդիա. Բացի սրանից նշվում են նաև փաթեթներ Libio-Socket-SSL-PERL и libnet-ssleay-perl, այնուամենայնիվ, դրանք պահանջվում են փոստով արդյունքներ ուղարկելու համար, ուստի դրանք անհրաժեշտ չեն, եթե դուք ընտրել եք ձեր զեկույցի առաքման այլ եղանակ:
Ֆունկցիա բեռնել_քաղվածք ներբեռնում և բացում է նշված արխիվը.
Ժամանակն է համատեղել նախագիծը: Դա տեղի է ունենում բաժնում ձեռագիր:
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
}
Փաստորեն, սա պարզեցված բնօրինակ կոնֆիգուրացիա է, բացառությամբ այս տողերի.
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Կոդի այս բաժնում մենք սահմանել ենք սմեյք դրոշ՝ կոմպիլացիոն հրամանների արտահանման համար: Սա անհրաժեշտ է ստատիկ կոդի անալիզատորի համար: Այս մասին ավելին կարող եք կարդալ հոդվածում «Ինչպես գործարկել PVS-Studio-ն Linux-ի և macOS-ի վրա»:
Եթե ժողովը հաջող է անցել, ուրեմն հասնում ենք հետո_հաջողություն, որտեղ մենք կատարում ենք ստատիկ վերլուծություն.
Առաջին տողը ստեղծում է լիցենզիայի ֆայլ այն օգտվողի անունից և բանալիից, որոնք մենք նշել ենք հենց սկզբում, երբ ստեղծեցինք Travis CI միջավայրի փոփոխականները:
Երկրորդ տողում ուղղակիորեն սկսվում է վերլուծությունը: Դրոշ -ժ սահմանում է վերլուծության համար նախատեսված թելերի քանակը, դրոշակ -լ ցույց է տալիս լիցենզիա, դրոշ -օ սահմանում է տեղեկամատյանների թողարկման ֆայլը և դրոշակը - անջատել Լիցենզիայի ժամկետի ստուգումը պահանջվում է փորձնական տարբերակների համար, քանի որ լռելյայն pvs-studio-անալիզատոր կզգուշացնի օգտվողին, որ լիցենզիայի ժամկետը սպառվում է: Որպեսզի դա տեղի չունենա, կարող եք նշել այս դրոշը:
Մատյան ֆայլը պարունակում է չմշակված ելք, որը հնարավոր չէ կարդալ առանց փոխակերպման, այնպես որ նախ պետք է ֆայլը ընթեռնելի դարձնել: Եկեք անցնենք գերանները լոգ-փոխարկիչ, իսկ ելքը html ֆայլ է։
Այս օրինակում ես որոշեցի ուղարկել հաշվետվություններ փոստով՝ օգտագործելով հրամանը ուղարկել նամակ.
Արդյունքում ստացանք հետևյալ ֆայլը .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;
Այժմ ժամանակն է փոփոխությունները մղել git պահեստում, որից հետո Travis CI-ն ավտոմատ կերպով կգործարկի build-ը: Կտտացրեք «ppsspp»՝ կառուցման հաշվետվություններին գնալու համար.
Մենք կտեսնենք ընթացիկ կառուցվածքի ակնարկ.
Եթե կառուցումը հաջողությամբ ավարտվի, մենք էլ-նամակ կստանանք ստատիկ վերլուծության արդյունքներով: Իհարկե, փոստը հաշվետվություն ստանալու միակ միջոցը չէ: Դուք կարող եք ընտրել իրականացման ցանկացած մեթոդ: Բայց հարկ է հիշել, որ կառուցման ավարտից հետո հնարավոր չի լինի մուտք գործել վիրտուալ մեքենայի ֆայլեր:
Սխալի ամփոփում
Մենք հաջողությամբ ավարտեցինք ամենադժվար մասը։ Հիմա եկեք համոզվենք, որ մեր բոլոր ջանքերն արժեն: Եկեք նայենք որոշ հետաքրքիր կետեր ստատիկ վերլուծության զեկույցից, որը ինձ հասավ փոստով (զուր չէ, որ ես դա նշեցի):
PVS-Studio նախազգուշացում. V597 Կազմողը կարող է ջնջել «memset» ֆունկցիայի կանչը, որն օգտագործվում է «sum» բուֆերը մաքրելու համար: RtlSecureZeroMemory() ֆունկցիան պետք է օգտագործվի մասնավոր տվյալները ջնջելու համար: sha1.cpp 325
Կոդի այս հատվածը գտնվում է ապահով հեշինգի մոդուլում, սակայն այն պարունակում է անվտանգության լուրջ թերություն (CWE-14) Եկեք նայենք հավաքման ցուցակին, որը ստեղծվում է Debug տարբերակը կազմելիս.
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Ամեն ինչ կարգին է և գործառույթը հուշագիր կատարվում է, դրանով իսկ վերագրանցելով կարևոր տվյալները RAM-ում, սակայն, դեռ մի ուրախացեք: Եկեք նայենք թողարկման տարբերակի հավաքագրմանը օպտիմալացումով.
Ինչպես երևում է ցուցակից, կոմպիլյատորն անտեսել է զանգը հուշագիր. Դա պայմանավորված է նրանով, որ գործառույթում sha1 զանգից հետո հուշագիր այլևս ոչ մի հղում կառուցվածքին ctx. Հետևաբար, կոմպիլյատորը իմաստ չի տեսնում ապագայում չօգտագործվող հիշողությունը վերագրանցելու համար պրոցեսորի ժամանակ վատնելը: Դուք կարող եք դա շտկել՝ օգտագործելով ֆունկցիան RtlSecureZero հիշողություն կամ նման նրան.
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-Studio նախազգուշացում. V547 «leftvol >= 0» արտահայտությունը միշտ ճիշտ է: sceAudio.cpp 120
Առաջինի համար ուշադրություն դարձրեք else ճյուղին if. Կոդը կկատարվի միայն բոլոր պայմանների դեպքում leftvol > 0xFFFF || rightvol > 0xFFFF || ձախվոլ < 0 || իրավունքը < 0 կստացվի, որ կեղծ է: Հետևաբար, մենք ստանում ենք հետևյալ պնդումները, որոնք ճշմարիտ կլինեն այլ ճյուղի համար. leftvol <= 0xFFFF, rightvol <= 0xFFFF, leftvol >= 0 и rightvol >= 0. Ուշադրություն դարձրեք վերջին երկու հայտարարություններին. Արդյո՞ք իմաստ ունի ստուգել, թե որն է անհրաժեշտ պայմանը այս կոդի կատարման համար:
Այսպիսով, մենք կարող ենք ապահով կերպով հեռացնել այս պայմանական հայտարարությունները.
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);
}
}
Մեկ այլ սցենար. Այս ավելորդ պայմանների հետևում թաքնված է ինչ-որ սխալ: Երևի չեն ստուգել, թե ինչ է պահանջվում։
V501 Կան միանման ենթարտահայտություններ «!Memory::IsValidAddress(psmfData)» «||»-ի ձախ և աջ կողմում: օպերատոր. scePsmf.cpp 703
Ուշադրություն դարձրեք ներսում գտնվող չեկին if. Տարօրինակ չե՞ք կարծում, որ մենք ստուգում ենք՝ արդյոք հասցեն վավեր է։ psmfData, կրկնակի ավել? Այսպիսով, սա ինձ տարօրինակ է թվում... Իրականում, սա, իհարկե, տառասխալ է, և գաղափարն այն էր, որ ստուգել երկու մուտքային պարամետրերը:
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-Studio նախազգուշացում. V547 «Չափ == 8» արտահայտությունը միշտ կեղծ է: syn-att.c 195
Այս սխալը գտնվում է թղթապանակում ներքին, այնպես որ իրականում չի համապատասխանում նախագծին, բայց սխալը հայտնաբերվել է նախքան ես նկատել եմ այն, ուստի ես որոշեցի թողնել այն: Ի վերջո, այս հոդվածը ոչ թե սխալների վերանայման, այլ Travis CI-ի հետ ինտեգրման մասին է, և անալիզատորի ոչ մի կոնֆիգուրացիա չի իրականացվել:
Փոփոխական Չափս սկզբնավորվում է հաստատունով, սակայն այն ընդհանրապես չի օգտագործվում կոդում՝ մինչև օպերատորը if, որը, իհարկե, տալիս է սուտ պայմանները ստուգելիս, քանի որ, ինչպես հիշում ենք, Չափս հավասար է զրոյի: Հետագա ստուգումները նույնպես իմաստ չունեն։
Ըստ երևույթին, կոդի հատվածի հեղինակը մոռացել է վերագրանցել փոփոխականը Չափս մինչ այդ։
Դադարեցնել
Այստեղ մենք հավանաբար կավարտենք սխալներով: Այս հոդվածի նպատակն է ցույց տալ PVS-Studio-ի աշխատանքը Travis CI-ի հետ միասին, այլ ոչ թե հնարավորինս մանրակրկիտ վերլուծել նախագիծը: Եթե ցանկանում եք ավելի մեծ ու գեղեցիկ սխալներ, միշտ կարող եք հիանալ դրանցով այստեղ :):
Ամփոփում
Ծրագրեր կառուցելու համար վեբ ծառայությունների օգտագործումը հավելյալ վերլուծության պրակտիկայի հետ միասին թույլ է տալիս գտնել բազմաթիվ խնդիրներ կոդի միաձուլումից անմիջապես հետո: Այնուամենայնիվ, մեկ կառուցումը կարող է բավարար չլինել, ուստի թեստավորումը ստատիկ վերլուծության հետ միասին կարգավորելը զգալիորեն կբարելավի կոդի որակը: