Ինչպես կարգավորել 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-ում:

Travis CI-ի կարգավորում

Մեզ անհրաժեշտ կլինի պահեստ GitHub-ում, որտեղ գտնվում է մեզ անհրաժեշտ նախագիծը, ինչպես նաև բանալի PVS-Studio-ի համար (կարող եք ստանալ փորձնական բանալի կամ անվճար բաց կոդով նախագծերի համար).

Եկեք գնանք կայք Թրևիս CI. Ձեր GitHub հաշիվն օգտագործելուց թույլտվությունից հետո մենք կտեսնենք պահեստների ցանկը.

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Փորձարկման համար ես պատառաքաղեցի PPSSPP:

Մենք ակտիվացնում ենք պահեստը, որը ցանկանում ենք հավաքել.

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Այս պահին Travis CI-ն չի կարող կառուցել մեր նախագիծը, քանի որ շինարարության հրահանգներ չկան: Այսպիսով, ժամանակն է կոնֆիգուրացիայի համար:

Վերլուծության ընթացքում որոշ փոփոխականներ օգտակար կլինեն մեզ համար, օրինակ՝ PVS-Studio-ի բանալին, որն անցանկալի կլիներ նշել կոնֆիգուրացիայի ֆայլում: Այսպիսով, եկեք ավելացնենք շրջակա միջավայրի փոփոխականներ՝ օգտագործելով Travis CI-ի կառուցման կարգավորումները.

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Մենք պետք է.

  • PVS_USERNAME - օգտվողի անուն
  • PVS_KEY - բանալի
  • MAIL_USER - էլփոստ, որը կօգտագործվի զեկույցն ուղարկելու համար
  • MAIL_PASSWORD - էլփոստի գաղտնաբառ

Վերջին երկուսը կամընտիր են: Դրանք կօգտագործվեն արդյունքները փոստով ուղարկելու համար: Եթե ​​ցանկանում եք հաշվետվությունը տարածել այլ կերպ, ապա ձեզ հարկավոր չէ դրանք նշել:

Այսպիսով, մենք ավելացրել ենք մեզ անհրաժեշտ շրջակա միջավայրի փոփոխականները.

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Հիմա եկեք ստեղծենք ֆայլ .travis.yml և տեղադրեք այն նախագծի արմատում: PPSSPP-ն արդեն ուներ կազմաձևման ֆայլ Travis CI-ի համար, այնուամենայնիվ, այն չափազանց մեծ էր և բացարձակապես ոչ պիտանի օրինակի համար, այնպես որ մենք ստիպված էինք մեծապես պարզեցնել այն և թողնել միայն հիմնական տարրերը:

Նախ, եկեք նշենք լեզուն, Ubuntu Linux-ի տարբերակը, որը մենք ցանկանում ենք օգտագործել վիրտուալ մեքենայում, և կառուցման համար անհրաժեշտ փաթեթները.

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'

Բոլոր փաթեթները, որոնք նշված են, անհրաժեշտ են բացառապես 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 փաստաթղթերը.

Մնում է միայն տրամադրել նախագծին հատուկ հավաքման հրահանգներ.

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-ն թույլ է տալիս ավելացնել ձեր սեփական հրամանները վիրտուալ մեքենայի կյանքի տարբեր փուլերի համար: Բաժին before_install կատարված փաթեթները տեղադրելուց առաջ: Հետո տեղադրել, որը հետևում է ցանկից փաթեթների տեղադրմանը addons.aptորը մենք նշեցինք վերևում։ Ժողովն ինքնին տեղի է ունենում ձեռագիր. Եթե ​​ամեն ինչ լավ է անցել, ուրեմն մենք հայտնվում ենք մեր մեջ հետո_հաջողություն (այս բաժնում է, որ մենք կկատարենք ստատիկ վերլուծություն): Սրանք բոլոր քայլերը չեն, որոնք կարելի է փոփոխել, եթե ձեզ ավելին է պետք, ապա պետք է նայեք Travis CI փաստաթղթերը.

Ընթերցանության հեշտության համար հրամանները տեղադրվեցին առանձին սցենարով .travis.sh, որը տեղադրված է նախագծի արմատում:

Այսպիսով, մենք ունենք հետևյալ ֆայլը .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

Նախքան փաթեթները տեղադրելը, մենք կթարմացնենք ենթամոդուլները։ Սա անհրաժեշտ է PPSSPP կառուցելու համար: Ավելացնենք առաջին ֆունկցիան .travis.sh (նկատի ունեցեք ընդլայնումը):

travis_before_install() {
  git submodule update --init --recursive
}

Այժմ մենք ուղղակիորեն գալիս ենք կարգավորելու 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, այնուամենայնիվ, դրանք պահանջվում են փոստով արդյունքներ ուղարկելու համար, ուստի դրանք անհրաժեշտ չեն, եթե դուք ընտրել եք ձեր զեկույցի առաքման այլ եղանակ:

Ֆունկցիա բեռնել_քաղվածք ներբեռնում և բացում է նշված արխիվը.

download_extract() {
  aria2c -x 16 $1 -o $2
  tar -xf $2
}

Ժամանակն է համատեղել նախագիծը: Դա տեղի է ունենում բաժնում ձեռագիր:

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_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
}

Եկեք մանրամասնորեն նայենք հետևյալ տողերին.

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

Առաջին տողը ստեղծում է լիցենզիայի ֆայլ այն օգտվողի անունից և բանալիից, որոնք մենք նշել ենք հենց սկզբում, երբ ստեղծեցինք 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-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Մենք կտեսնենք ընթացիկ կառուցվածքի ակնարկ.

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը
Եթե ​​կառուցումը հաջողությամբ ավարտվի, մենք էլ-նամակ կստանանք ստատիկ վերլուծության արդյունքներով: Իհարկե, փոստը հաշվետվություն ստանալու միակ միջոցը չէ: Դուք կարող եք ընտրել իրականացման ցանկացած մեթոդ: Բայց հարկ է հիշել, որ կառուցման ավարտից հետո հնարավոր չի լինի մուտք գործել վիրտուալ մեքենայի ֆայլեր:

Սխալի ամփոփում

Մենք հաջողությամբ ավարտեցինք ամենադժվար մասը։ Հիմա եկեք համոզվենք, որ մեր բոլոր ջանքերն արժեն: Եկեք նայենք որոշ հետաքրքիր կետեր ստատիկ վերլուծության զեկույցից, որը ինձ հասավ փոստով (զուր չէ, որ ես դա նշեցի):

Վտանգավոր օպտիմիզացում

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 նախազգուշացում. 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-ում, սակայն, դեռ մի ուրախացեք: Եկեք նայենք թողարկման տարբերակի հավաքագրմանը օպտիմալացումով.

; 354  :
; 355  :  memset( sum, 0, sizeof( sum ) );
; 356  :}

Ինչպես երևում է ցուցակից, կոմպիլյատորն անտեսել է զանգը հուշագիր. Դա պայմանավորված է նրանով, որ գործառույթում sha1 զանգից հետո հուշագիր այլևս ոչ մի հղում կառուցվածքին ctx. Հետևաբար, կոմպիլյատորը իմաստ չի տեսնում ապագայում չօգտագործվող հիշողությունը վերագրանցելու համար պրոցեսորի ժամանակ վատնելը: Դուք կարող եք դա շտկել՝ օգտագործելով ֆունկցիան RtlSecureZero հիշողություն կամ նման նրան.

Ճիշտ:

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 ) );
} 

Ավելորդ համեմատություն

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);
  }
}

Մեկ այլ սցենար. Այս ավելորդ պայմանների հետևում թաքնված է ինչ-որ սխալ: Երևի չեն ստուգել, ​​թե ինչ է պահանջվում։

Ctrl+C Ctrl+V հակահարված է տալիս

static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
  if (!Memory::IsValidAddress(psmfData) ||
      !Memory::IsValidAddress(psmfData)) {
    return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
  }
  ....
}

V501 Կան միանման ենթարտահայտություններ «!Memory::IsValidAddress(psmfData)» «||»-ի ձախ և աջ կողմում: օպերատոր. scePsmf.cpp 703

Ուշադրություն դարձրեք ներսում գտնվող չեկին if. Տարօրինակ չե՞ք կարծում, որ մենք ստուգում ենք՝ արդյոք հասցեն վավեր է։ psmfData, կրկնակի ավել? Այսպիսով, սա ինձ տարօրինակ է թվում... Իրականում, սա, իհարկե, տառասխալ է, և գաղափարն այն էր, որ ստուգել երկու մուտքային պարամետրերը:

Ճիշտ տարբերակ.

static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
  if (!Memory::IsValidAddress(psmfStruct) ||
      !Memory::IsValidAddress(psmfData)) {
    return hleReportError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad address");
  }
  ....
}

Մոռացված փոփոխական

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-ի հետ միասին, այլ ոչ թե հնարավորինս մանրակրկիտ վերլուծել նախագիծը: Եթե ​​ցանկանում եք ավելի մեծ ու գեղեցիկ սխալներ, միշտ կարող եք հիանալ դրանցով այստեղ :):

Ամփոփում

Ծրագրեր կառուցելու համար վեբ ծառայությունների օգտագործումը հավելյալ վերլուծության պրակտիկայի հետ միասին թույլ է տալիս գտնել բազմաթիվ խնդիրներ կոդի միաձուլումից անմիջապես հետո: Այնուամենայնիվ, մեկ կառուցումը կարող է բավարար չլինել, ուստի թեստավորումը ստատիկ վերլուծության հետ միասին կարգավորելը զգալիորեն կբարելավի կոդի որակը:

Օգտակար հղումներ

Ինչպես կարգավորել PVS-Studio-ն Travis CI-ում, օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը

Եթե ​​ցանկանում եք կիսվել այս հոդվածով անգլիախոս լսարանի հետ, խնդրում ենք օգտագործել թարգմանության հղումը՝ Մաքսիմ Զվյագինցև։ Ինչպես ստեղծել PVS-Studio-ն Travis CI-ում՝ օգտագործելով PSP խաղային կոնսոլի էմուլյատորի օրինակը.

Source: www.habr.com

Добавить комментарий