Ang Travis CI usa ka gipang-apod-apod nga serbisyo sa web alang sa pagtukod ug pagsulay sa software nga naggamit sa GitHub isip source code hosting. Dugang pa sa mga senaryo sa pag-opera sa ibabaw, mahimo nimong idugang ang imong kaugalingon nga salamat sa daghang mga kapilian sa pag-configure. Niini nga artikulo atong i-configure ang Travis CI aron magtrabaho sa PVS-Studio gamit ang PPSSPP code example.
Pasiuna
Pag-set up sa Travis CI
Kinahanglan namon ang usa ka repository sa GitHub, diin nahimutang ang proyekto nga among gikinahanglan, ingon man usa ka yawe alang sa PVS-Studio (makuha nimo
Adto ta sa site
Alang sa pagsulay, akong gi-fork ang PPSSPP.
Among gi-activate ang repository nga gusto namong kolektahon:
Sa pagkakaron, ang Travis CI dili makatukod sa among proyekto tungod kay walay mga instruksyon alang sa pagtukod. Mao nga panahon na alang sa pag-configure.
Atol sa pagtuki, pipila ka mga baryable mahimong mapuslanon kanato, alang sa panig-ingnan, ang yawe alang sa PVS-Studio, nga dili gusto nga espesipiko sa configuration file. Mao nga idugang naton ang mga variable sa palibot gamit ang mga setting sa pagtukod sa Travis CI:
Kinahanglan namon:
- PVS_USERNAME - username
- PVS_KEY - yawe
- MAIL_USER - email nga gamiton sa pagpadala sa taho
- MAIL_PASSWORD - password sa email
Ang kataposang duha maoy opsyonal. Kini gamiton sa pagpadala sa mga resulta pinaagi sa koreo. Kung gusto nimo nga ipang-apod-apod ang taho sa lain nga paagi, dili nimo kinahanglan ipahibalo kini.
Mao nga, gidugang namon ang mga variable sa palibot nga kinahanglan namon:
Karon maghimo kita ug file .travis.yml ug ibutang kini sa gamut sa proyekto. Ang PPSSPP aduna nay configuration file alang sa Travis CI, bisan pa, kini dako kaayo ug hingpit nga dili angay alang sa panig-ingnan, mao nga kinahanglan namon nga pasimplehon kini ug ibilin lamang ang mga batakang elemento.
Una, atong ipakita ang pinulongan, ang bersyon sa Ubuntu Linux nga gusto natong gamiton sa virtual machine, ug ang gikinahanglan nga mga pakete alang sa pagtukod:
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'
Ang tanan nga mga pakete nga nalista gikinahanglan alang lamang sa PPSSPP.
Karon among gipakita ang assembly matrix:
matrix:
include:
- os: linux
compiler: "gcc"
env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
- os: linux
compiler: "clang"
env: PPSSPP_BUILD_TYPE=Linux
Usa ka gamay pa bahin sa seksyon taguangkan sa. Sa Travis CI, adunay duha ka mga paagi sa paghimo sa mga kapilian sa pagtukod: ang una mao ang pagtino sa usa ka lista sa mga compiler, mga tipo sa operating system, mga variable sa palibot, ug uban pa, pagkahuman ang usa ka matrix sa tanan nga posible nga mga kombinasyon gihimo; ang ikaduha mao ang tin-aw nga timailhan sa matrix. Siyempre, mahimo nimong isagol kining duha ka mga pamaagi ug makadugang usa ka talagsaon nga kaso, o, sa kasukwahi, dili iapil kini gamit ang seksyon iapil. Mahimo nimong mabasa ang dugang bahin niini sa
Ang nahabilin mao ang paghatag mga panudlo sa asembliya nga piho sa proyekto:
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
Gitugotan ka sa Travis CI nga idugang ang imong kaugalingon nga mga mando alang sa lainlaing mga yugto sa kinabuhi sa usa ka virtual machine. Seksyon before_install gipatuman sa wala pa i-install ang mga pakete. Unya pag-instalar, nga nagsunod sa pag-instalar sa mga pakete gikan sa listahan addons.aptnga among gipakita sa ibabaw. Ang asembliya mismo mahitabo sa script. Kung maayo ang tanan, nan makita namon ang among kaugalingon pagkahuman_kalamposan (anaa niini nga seksyon nga magpadagan kami sa static nga pagtuki). Dili kini tanan nga mga lakang nga mahimoβg mabag-o, kung kinahanglan nimo ang labi pa, kinahanglan nimo nga tan-awon
Alang sa kasayon ββsa pagbasa, ang mga sugo gibutang sa usa ka bulag nga script .travis.sh, nga gibutang sa gamut sa proyekto.
Busa kami adunay mosunod nga file .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
Sa dili pa i-install ang mga pakete, among i-update ang mga submodules. Kini gikinahanglan aron matukod ang PPSSPP. Atong idugang ang unang function sa .travis.sh (Tan-awa ang extension):
travis_before_install() {
git submodule update --init --recursive
}
Karon direkta na kami sa pag-set up sa awtomatikong paglansad sa PVS-Studio sa Travis CI. Una kinahanglan natong i-install ang PVS-Studio nga pakete sa sistema:
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
}
Sa pagsugod sa function travis_install among gi-install ang mga compiler nga among gikinahanglan gamit ang environment variables. Unya kung ang variable $PVS_ANALYZE bili sa mga tindahan Oo (gipakita namo kini sa seksyon env atol sa pagtukod sa matrix configuration), atong i-install ang package pvs-studio. Dugang pa niini, gipakita usab ang mga pakete libio-socket-ssl-perl ΠΈ libnet-ssleay-perl, bisan pa, gikinahanglan kini alang sa mga resulta sa pagpadala, mao nga dili kini kinahanglan kung nagpili ka og lain nga pamaagi sa paghatud sa imong taho.
function download_extract i-download ug i-unpack ang gipiho nga archive:
download_extract() {
aria2c -x 16 $1 -o $2
tar -xf $2
}
Panahon na aron mahiusa ang proyekto. Kini mahitabo sa seksyon script:
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
}
Sa tinuud, kini usa ka gipasimple nga orihinal nga pagsumpo, gawas sa kini nga mga linya:
if [ "$PVS_ANALYZE" = "Yes" ]; then
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi
Niini nga seksyon sa code nga among gitakda cmake bandila alang sa pag-eksport sa mga kompilasyon nga mga sugo. Kini gikinahanglan alang sa usa ka static code analyzer. Mahimo nimong mabasa ang dugang bahin niini sa artikulo nga "
Kung ang asembliya nagmalampuson, nan kita sa pagkahuman_kalamposan, diin among gihimo ang static nga pagtuki:
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
}
Atong tan-awon pag-ayo ang mosunod nga mga linya:
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
Ang una nga linya nagmugna usa ka file sa lisensya gikan sa username ug yawe nga among gipiho sa sinugdanan sa pag-set up sa mga variable sa palibot sa Travis CI.
Ang ikaduha nga linya magsugod sa pagtuki direkta. Bandila -j nagtakda sa gidaghanon sa mga hilo alang sa pagtuki, bandila -l nagpaila sa lisensya, bandila -o naghubit sa file alang sa pag-output sa mga troso, ug ang bandila -disableLicenseExpirationCheck gikinahanglan alang sa pagsulay nga mga bersyon, tungod kay pinaagi sa default pvs-studio-analyzer magpasidaan sa tiggamit nga ang lisensya hapit na ma-expire. Aron mapugngan kini nga mahitabo, mahimo nimong itakda kini nga bandila.
Ang log file adunay hilaw nga output nga dili mabasa kung wala ang pagkakabig, mao nga kinahanglan nimo nga himuon nga mabasa ang file. Ipasa nato ang mga troso tigbalhin-balhin, ug ang output kay html file.
Sa kini nga pananglitan, nakahukom ako nga magpadala mga taho pinaagi sa koreo gamit ang mando sendemail.
Ingon usa ka sangputanan, nakuha namon ang mosunud nga file .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;
Karon na ang panahon nga iduso ang mga pagbag-o sa git repository, pagkahuman ang Travis CI awtomatik nga magpadagan sa pagtukod. Pag-klik sa "ppsspp" aron makaadto sa mga report sa pagtukod:
Atong makita ang usa ka kinatibuk-ang ideya sa kasamtangan nga pagtukod:
Kung malampuson nga nahuman ang pagtukod, makadawat kami usa ka email nga adunay mga resulta sa static nga pagtuki. Siyempre, ang pagpadala dili lamang ang paagi aron makadawat usa ka taho. Mahimo nimong pilion ang bisan unsang pamaagi sa pagpatuman. Apan importante nga hinumdoman nga human makompleto ang pagtukod, dili posible nga ma-access ang mga file sa virtual machine.
Summary sa sayop
Malampuson namo nga nahuman ang pinakalisud nga bahin. Karon atong siguroon nga ang tanan natong mga paningkamot takus niini. Atong tan-awon ang pipila ka makapaikag nga mga punto gikan sa static nga taho sa pagtuki nga mianhi kanako pinaagi sa koreo (dili alang sa bisan unsa nga akong gipakita kini).
Delikado nga pag-optimize
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-Studio pasidaan:
Kini nga piraso sa code nahimutang sa luwas nga hashing module, bisan pa, kini adunay usa ka seryoso nga sayup sa seguridad (
; Line 355
mov r8d, 20
xor edx, edx
lea rcx, QWORD PTR sum$[rsp]
call memset
; Line 356
Ang tanan naa sa kahusay ug ang function memeset gipatuman, sa ingon gi-overwrite ang hinungdanon nga datos sa RAM, bisan pa, ayaw pagmaya. Atong tan-awon ang listahan sa asembliya sa Release nga bersyon nga adunay pag-optimize:
; 354 :
; 355 : memset( sum, 0, sizeof( sum ) );
; 356 :}
Ingon sa makita gikan sa listahan, ang compiler wala magtagad sa tawag memeset. Kini tungod sa kamatuoran nga sa function sha1 pagkahuman sa tawag memeset wala nay pakisayran sa istruktura CTx. Busa, ang compiler walay nakita nga punto sa pag-usik sa oras sa processor sa pag-overwrit sa memorya nga wala magamit sa umaabot. Mahimo nimo kini ayuhon pinaagi sa paggamit sa function RtlSecureZeroMemory o
Husto nga:
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 ) );
}
Dili kinahanglan nga pagtandi
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 pasidaan:
Hatagi'g pagtagad ang laing sanga alang sa una if. Ang code ipatuman lamang kung ang tanan nga mga kondisyon leftvol > 0xFFFF || rightvol > 0xFFFF || leftvol < 0 || kanangvol < 0 mahimong bakak. Busa, atong makuha ang mosunod nga mga pahayag, nga mahimong tinuod alang sa laing sanga: leftvol <= 0xFFFF, rightvol <= 0xFFFF, leftvol >= 0 ΠΈ rightvol >= 0. Matikdi ang kataposang duha ka pahayag. Makatarunganon ba nga susihon kung unsa ang kinahanglan nga kondisyon alang sa pagpatuman niini nga piraso sa code?
Busa luwas natong matangtang kining mga kondisyonal nga pahayag:
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);
}
}
Laing senaryo. Adunay usa ka matang sa sayup nga gitago sa luyo niining sobra nga mga kondisyon. Tingali wala nila susihon kung unsa ang gikinahanglan.
Ctrl+C Ctrl+V mibalik
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfData) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Hatagi'g pagtagad ang tseke sa sulod if. Dili ba katingad-an nga atong susihon kung balido ang adres? psmfData, doble pa? Mao nga kini ingon katingad-an alang kanako ... Sa tinuud, kini, siyempre, usa ka typo, ug ang ideya mao ang pagsusi sa duha nga mga parameter sa input.
Sakto nga opsyon:
static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
if (!Memory::IsValidAddress(psmfStruct) ||
!Memory::IsValidAddress(psmfData)) {
return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
}
....
}
Nakalimtan nga variable
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 pasidaan:
Kini nga sayup nahimutang sa folder ext, mao nga dili gyud angay sa proyekto, apan ang bug nakit-an sa wala pa nako kini mamatikdan, mao nga nakahukom ko nga biyaan kini. Pagkahuman, kini nga artikulo dili bahin sa pagrepaso sa mga sayup, apan bahin sa panagsama sa Travis CI, ug walaβy gihimo nga pag-configure sa analisador.
Variable gidak-on gisugdan pinaagi sa usa ka kanunay, bisan pa, wala kini gigamit sa tanan sa code, hangtod sa operator if, nga, siyempre, naghatag bakak nga mga samtang gisusi ang mga kondisyon, tungod kay, sa atong nahinumduman, gidak-on katumbas sa sero. Ang sunod nga mga tseke usab walay kahulogan.
Dayag, ang tagsulat sa tipik sa code nakalimot sa pag-overwrite sa variable gidak-on sa wala pa kana.
Hunong
Dinhi tingali kita matapos sa mga kasaypanan. Ang katuyoan sa kini nga artikulo mao ang pagpakita sa buhat sa PVS-Studio kauban ang Travis CI, ug dili aron analisahon ang proyekto sa hingpit kutob sa mahimo. Kung gusto nimo ang labi ka dako ug labi ka matahum nga mga sayup, mahimo nimo kini kanunay nga makadayeg
konklusyon
Ang paggamit sa mga serbisyo sa web aron magtukod mga proyekto kauban ang pagpraktis sa incremental analysis nagtugot kanimo nga makit-an ang daghang mga problema pagkahuman dayon sa paghiusa sa code. Bisan pa, ang usa ka pagtukod mahimoβg dili igo, mao nga ang pag-set up sa pagsulay kauban ang static nga pag-analisar labi nga makapauswag sa kalidad sa code.
Mapuslanon nga mga link
Kung gusto nimong ipaambit kini nga artikulo sa usa ka tigpaminaw nga nagsultig English, palihug gamita ang link sa paghubad: Maxim Zvyagintsev.
Source: www.habr.com