如何使用PSP游戏机模拟器的示例在Travis CI中设置PVS-Studio

PPSSPP

Travis CI is a distributed web service for building and testing software that uses GitHub as a source code hosting service. In addition to the above scripts, you can add your own, thanks to the extensive configuration options. In this article we will set up Travis CI for working with PVS-Studio by the example of PPSSPP code.

Travis CI是用于构建和测试软件的分布式Web服务,该服务使用GitHub作为源代码托管服务。 除了上述脚本,您还可以添加自己的脚本,这要归功于广泛的配置选项。 在本文中,我们将通过PPSSPP代码示例将Travis CI设置为可与PVS-Studio一起使用。

介绍 (Introduction)

Travis CI is a web service for building and testing software. It is usually used in combination with the practice of continuous integration. Travis CI是用于构建和测试软件的Web服务。 它通常与持续集成的实践结合使用。 PPSSPP is an emulator of PSP game console. The program is able to emulate the launch of any game with images of discs designed for Sony PSP. The program was released on November 1, 2012. PPSSPP is distributed under GPL v2 license. Anyone can make improvements to the PPSSPP是PSP游戏机的模拟器。 该程序可以使用为Sony PSP设计的光盘映像来模拟任何游戏的启动。 该程序于2012年11月1日发布。PPSSPP是根据GPL v2许可发行的。 任何人都可以对项目的 source code of the project. 源代码进行改进。 PVS-Studio — static code analyzer for searching errors and potential vulnerabilities in program code. In this article, we will launch PVS-Studio in the cloud instead of locally on the developer's computer for a variety of purposes and will search for errors in PPSSPP. PVS-Studio —静态代码分析器,用于搜索程序代码中的错误和潜在漏洞。 在本文中,出于各种目的,我们将在云中启动PVS-Studio,而不是在开发人员的计算机上本地启动PVS-Studio,并将搜索PPSSPP中的错误。

Travis CI成立 (Travis CI set up)

We will need a repository on GitHub where the project we need is located, as well as a key for PVS-Studio (you can get a trial key or a free one for Open Source projects).

我们将需要在GitHub上找到我们需要的项目所在的存储库,以及PVS-Studio的密钥(您可以为开放源代码项目获得一个试用密钥免费的 密钥 )。

Let's go to Travis CI site. After authorization with the help of GitHub account we will have a list of repositories:

让我们去Travis CI网站。 在GitHub帐户的帮助下进行授权后,我们将获得一个存储库列表:

For the test, I made a PPSSPP fork.

为了进行测试,我制作了一个PPSSPP叉子。

We activate the repository which we want to build:

我们激活要构建的存储库:

At the moment, Travis CI can't build our project because there are no instructions for building it. That's why it's time for the configuration.

目前,Travis CI无法构建我们的项目,因为没有有关构建它的说明。 这就是为什么要进行配置了。

During the analysis we will need some variables, for example, the key for PVS-Studio, which would be undesirable to specify in the configuration file. So, let's add environment variables by configuring the build in Travis CI:

在分析过程中,我们将需要一些变量,例如PVS-Studio的密钥,这在配置文件中无法指定。 因此,让我们通过在Travis CI中配置构建来添加环境变量:

We will need:

我们会需要:

  • PVS_USERNAME – user name

    PVS_USERNAME –用户名
  • PVS_KEY — key

    PVS_KEY-键
  • MAIL_USER — email that will be used to send the report

    MAIL_USER —将用于发送报告的电子邮件
  • MAIL_PASSWORD – email password

    MAIL_PASSWORD –电子邮件密码

The last two are optional. They will be used to send the results by mail. If you want to send the report in another way, you do not need to specify them.

最后两个是可选的。 它们将用于通过邮件发送结果。 如果要以其他方式发送报告,则无需指定它们。

So, we have added the environment variables we need:

因此,我们添加了所需的环境变量:

Now let's create a .travis.yml file and put it in the root of the project. PPSSPP already had a configuration file for Travis CI, however, it was too large and not suitable for the example, so we had to simplify it and leave only the basic elements.

现在,让我们创建一个.travis.yml文件,并将其放在项目的根目录中。 PPSSPP已经有Travis CI的配置文件,但是它太大,不适合该示例,因此我们必须对其进行简化,只保留基本元素。

First, let's specify the programming language, the version of Ubuntu Linux that we want to use on the virtual machine, and the necessary packages for building:

首先,让我们指定编程语言,我们要在虚拟机上使用的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'

All added packages are only needed for PPSSPP.

所有添加的软件包仅对于PPSSPP才需要。

Now specify the building matrix:

现在指定建筑物矩阵:

matrix:
  include:
    - os: linux
      compiler: "gcc"
      env: PPSSPP_BUILD_TYPE=Linux PVS_ANALYZE=Yes
    - os: linux
      compiler: "clang"
      env: PPSSPP_BUILD_TYPE=Linux

A bit more about the matrix section. In Travis CI there are two ways to create build variants: the first one is to specify compilers, types of operating systems, environment variables etc. with the list, after which the matrix of all possible combinations will be generated; the second one is an explicit indication of the matrix. Of course, you can combine these two approaches and add a unique case, or, on the contrary, exclude it by using the exclude section. You can read more about this in the Travis CI documentation.

有关矩阵部分的更多信息。 在Travis CI中,有两种创建构建变体的方法:第一种是使用列表指定编译器,操作系统类型,环境变量等,然后将生成所有可能组合的矩阵。 第二个是矩阵的明确指示。 当然,您可以将这两种方法结合起来并添加一个唯一的大小写,或者相反,可以使用排除部分将其排除 。 您可以在Travis CI文档中阅读有关此内容的更多信息。

The only thing left to do is to specify project-specific build instructions:

剩下要做的就是指定特定于项目的构建说明:

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 allows you to add your own commands for different stages of virtual machine life. The before_install section runs before installing the packages. Then install, which follows the installation of the packages from the addons.apt list that we have specified above. The build itself takes place in script. If everything has been successful, we get into after_success (this is where we will start static analysis). These are not all the steps you can modify, if you need more, you should look in the documentation on Travis CI.

Travis CI允许您为虚拟机生命的不同阶段添加自己的命令。 在安装软件包之前, before_install节运行。 然后安装 ,这将在上面指定的addons.apt列表中安装软件包。 构建本身在script中进行 。 如果一切都成功,那么我们进入after_success (在这里我们将开始静态分析)。 这些不是您可以修改的所有步骤,如果需要更多步骤,则应查看Travis CI上文档

For the convenience of reading the commands were put into a separate script .travis.sh, which is placed in the root of the project.

为了方便阅读,将命令放入单独的脚本.travis.sh中 ,该脚本位于项目的根目录中。

So, we have the following file .travis.yml:

因此,我们有以下文件.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

Before installing the packages, let's update the submodules. This is necessary to build PPSSPPs. Add the first function to .travis.sh (note the extension):

在安装软件包之前,让我们更新子模块。 这是构建PPSSPP所必需的。 将第一个函数添加到.travis.sh (注意扩展名):

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

Now we've come directly to setting up the automatic launch of PVS-Studio in Travis CI. First, we need to install the PVS-Studio package into the system:

现在我们直接在Travis CI中设置自动启动PVS-Studio。 首先,我们需要将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
}

At the beginning of the travis_install function we install the compilers we need using environment variables. Then, if the $PVS_ANALYZE variable stores the value of Yes (we specified it in the env section when configuring the build matrix), we install the pvs-studio package. Besides it, there are also libio-socket-ssl-perl and libnet-ssleay-perl packages, but they are needed to send the results by mail, so they are not necessary if you have chosen another way of report delivery.

travis_install函数的开头,我们使用环境变量安装所需的编译器。 然后,如果$ PVS_ANALYZE变量存储了Yes的值(在配置构建矩阵时,我们在env部分中指定了它),则将安装pvs-studio软件包。 除此之外,还有libio-socket-ssl-perllibnet-ssleay-perl软件包,但是通过邮件发送结果是必需的,因此,如果您选择了另一种报告传递方式,则不需要它们。

The download_extract function downloads and unpacks the specified archive:

download_extract函数下载并解压缩指定的归档文件:

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

It's time to build a project. This happens in the script section:

现在是构建项目的时候了。 这发生在脚本部分:

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
}

In fact, this is a simplified original configuration, except for these lines:

实际上,这是简化的原始配置,但以下几行除外:

if [ "$PVS_ANALYZE" = "Yes" ]; then
  CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
fi

In this section of the code, we set the compilation command export flag for cmake. This is necessary for a static code analyzer. You may read more about it in the article "How to launch PVS-Studio in Linux and macOS".

在代码的这一部分,我们将编译命令export标志设置为cmake 。 这对于静态代码分析器是必需的。 您可以在文章“ 如何在Linux和macOS中启动PVS-Studio ”中阅读有关它的更多信息。

If the build was successful, we will get to after_success where we will run static analysis:

如果构建成功,我们将进入after_success ,在此我们将运行静态分析:

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 mail@domain.com \
              -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
}

Let's consider the following lines in detail:

让我们详细考虑以下几行:

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

The first line generates the license file from the user name and the key that we specified at the beginning of the configuration of the Travis CI environment variables.

第一行从用户名和我们在Travis CI环境变量的配置开始时指定的密钥生成许可证文件。

The second line starts the analysis directly. The flag -j<N> sets the number of analysis threads, the flag -l <file> sets the license, the flag -o <file> sets the file to output the logs, and the flag -disableLicenseExpirationCheck is necessary for trial versions, because by default pvs-studio-analyzer will warn the user about the imminent expiration of the license. To prevent this from happening, you can specify this flag.

第二行直接开始分析。 标志-j <N>设置分析线程的数量,标志-l <file>设置许可证,标志-o <file>设置文件以输出日志,标志-disableLicenseExpirationCheck对于试用版是必需的,因为默认情况下pvs-studio-analyzer会警告用户许可证即将到期。 为防止这种情况发生,您可以指定此标志。

The log file contains an unprocessed output that cannot be read without conversion, so first you need to make the file readable. Let's run the logs through plog-converter and get an html file at the output.

日志文件包含未经处理的输出,未经转换就无法读取,因此首先需要使文件可读。 让我们通过plog-converter运行日志,并在输出中获取一个html文件。

In this example I decided to send reports by mail using the sendemail command.

在此示例中,我决定使用sendemail命令通过邮件发送报告。

The result was the following .travis.sh 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 mail@domain.com \
              -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;

It's time to add the changes to the git repository, and then Travis CI will automatically start the build. Click on «ppsspp» to go to build reports:

现在是将更改添加到git存储库的时候了,然后Travis CI将自动开始构建。 点击《 ppsspp》以建立报告:

We will see an overview of the current build:

我们将看到当前构建的概述:

If the build is successfully completed, we will receive an e-mail with the results of static analysis. Of course, sending by mail is not the only way to get the report. You can choose any method of implementation. But it is important to remember that it will be impossible to get access to the files of the virtual machine after the build is finished.

如果构建成功完成,我们将收到一封包含静态分析结果的电子邮件。 当然,通过邮件发送不是获取报告的唯一方法。 您可以选择任何实现方法。 但是请务必记住,构建完成后将无法访问虚拟机的文件。

错误简要概述 (Brief overview of errors)

We have successfully completed the most difficult part. Let us now make sure that all our efforts have been justified. Let's consider some interesting points from the static analysis report that came to me by mail (it's not for nothing that I specified it).

我们已经成功完成了最困难的部分。 现在让我们确保我们所有的努力都是合理的。 让我们考虑一下通过邮件发送给我的静态分析报告中的一些有趣的观点(我没有特别指出)。

危险的优化 (Dangerous optimizations)

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

The PVS-Studio warning: V597 The compiler could delete the 'memset' function call, which is used to flush 'sum' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. sha1.cpp 325

PVS-Studio警告: V597编译器可以删除“ 内存集 ”函数调用,该函数调用用于刷新“求和”缓冲区。 RtlSecureZeroMemory()函数应用于擦除私有数据。 sha1.cpp 325

This code fragment is located in the secure hashing module, but it contains a serious security defect (CWE-14). Let's consider the assembler listing which is generated when the Debug-version compiles:

此代码片段位于安全哈希模块中,但其中包含严重的安全缺陷( CWE-14 )。 让我们考虑一下Debug-version编译时生成的汇编列表:

; Line 355
  mov r8d, 20
  xor edx, edx
  lea rcx, QWORD PTR sum$[rsp]
  call memset
; Line 356

Everything is fine and the memset function is executed, thus wiping important data in RAM, but you shouldn't be glad yet. Let's consider assembler listing of the Release version with optimization:

一切都很好,并且执行了memset函数,从而擦除了RAM中的重要数据,但是您还不高兴。 让我们考虑经过优化的发行版的汇编程序列表:

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

As you can see from the listing, the compiler ignored the call of memset. It is related to the fact that the sha1 function no longer calls the ctx structure after calling memset. That's why the compiler doesn't see any sense in wasting processor time on overwriting memory not being used in future. You may fix it by using the RtlSecureZeroMemory function or a similar function.

从清单中可以看到,编译器忽略了memset的调用。 这与以下事实有关: sha1函数在调用memset之后不再调用ctx结构。 这就是为什么编译器看不到浪费处理器时间以覆盖将来不使用的内存的任何意义。 您可以使用RtlSecureZeroMemory函数或类似的函数来修复它。

Right:

对:

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

不必要的比较 (Unnecessary comparison)

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

The PVS-Studio warning: V547 Expression 'leftvol >= 0' is always true. sceAudio.cpp 120

PVS-Studio警告: V547表达式'leftvol> = 0'始终为true。 sceAudio.cpp 120

Pay attention to the else branch for the first if. The code will be executed only if all the conditions leftvol > 0xFFFFF || rightvol > 0xFFFF || leftvol < 0 || rightvol < 0 are false. Therefore, we get the following statements that will be true for the else branch: leftvol <= 0xFFFFF, rightvol <= 0xFFFFF, leftvol >= 0 and rightvol >= 0. Pay attention to the last two statements. Is it reasonable to check what is the necessary condition of execution of this code fragment?

注意第一个if的else分支。 仅当所有条件leftvol> 0xFFFFF ||时 ,代码才会执行​​。 rightvol> 0xFFFF || leftvol <0 || rightvol <0为假。 因此,我们得到以下对于else分支正确的语句: leftvol <= 0xFFFFF,rightvol <= 0xFFFFF,leftvol> = 0和rightvol> = 0 。 注意最后两个语句。 检查执行此代码片段的必要条件是否合理?

So we can calmly delete these conditional operators:

因此,我们可以冷静地删除这些条件运算符:

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

Another scenario. Behind these redundant conditions there is some error. Perhaps we have checked what is not what we need…

另一种情况。 这些冗余条件的后面有一些错误。 也许我们已经检查了不是我们所需要的……

Ctrl + C Ctrl + V反击 (Ctrl+C Ctrl+V strikes back)

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 There are identical sub-expressions '!Memory::IsValidAddress(psmfData)' to the left and to the right of the '||' operator. scePsmf.cpp 703 V501在“ ||”的左侧和右侧有相同的子表达式“!Memory :: IsValidAddress(psmfData)” 操作员。 scePsmf.cpp 703

Note the check inside if. Doesn't it seem strange to you that we are checking whether the psmfData address is valid twice as much? So I find it strange… Actually, we have a misprint before us, of course, and the idea was to check both input parameters.

注意检查里面是否 。 您正在检查psmfData地址是否是有效地址的两倍,对您来说似乎并不奇怪吗? 因此,我感到很奇怪……实际上,我们当然要摆错一个标签,其想法是检查两个输入参数。

The correct variant is:

正确的变体是:

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

被遗忘的变量 (Forgotten 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");
  }
  ....
}

The PVS-Studio warning: V547 Expression 'size == 8' is always false. syn-att.c 195

PVS-Studio警告: V547表达式'size == 8'始终为false。 195

This error is located in the ext folder, so it doesn't really apply to the project, but the error was found before I noticed it, so I decided to keep it. Still, this article is not about error review but about integration with Travis CI and no analyzer configuration was performed.

该错误位于ext文件夹中,因此它实际上并不适用于项目,但是在我注意到该错误之前就已发现该错误,因此我决定保留此错误。 仍然,本文不是关于错误检查,而是关于与Travis CI的集成,并且没有执行分析器配置。

The size variable is initialized with a constant, but it is not used at all in the code up to the if operator which, of course, generates false information while checking the condition because, as we remember, the size is equal to zero. Subsequent checks do not make sense either.

size变量是用常量初始化的,但是直到if运算符为止,它在代码中根本没有使用,当然, if运算符会在检查条件时生成错误信息,因为我们记得, size等于零。 后续检查也没有意义。

Apparently, the author of the code fragment forgot to overwrite the size variable before that.

显然,代码片段的作者在此之前忘记了覆盖size变量。

停止 (Stop)

That's where we're gonna stop with the errors. The purpose of this article is to demonstrate how PVS-Studio works with Travis CI and not to analyze the project as thoroughly as possible. If you want bigger and more beautiful errors, you can always see them here :).

那就是我们要停止错误的地方。 本文的目的是演示PVS-Studio如何与Travis CI配合使用,而不是尽可能全面地分析项目。 如果您想要更大更漂亮的错误,可以随时在这里查看它们:)。

结论 (Conclusion)

Using web services for building projects together with incremental analysis practice allows you to detect many problems right after the code merge. However, one build may not be enough, so setting up testing together with static analysis will significantly improve the code quality.

将Web服务与增量分析实践一起用于构建项目,可以使您在代码合并后立即发现许多问题。 但是,一个构建可能还不够,因此将测试与静态分析一起设置将大大提高代码质量。

有用的链接 (Useful Links)

翻译自: https://habr.com/en/company/pvs-studio/blog/464641/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值