SlideShare a Scribd company logo
1 of 13
Download to read offline
PVS-Studio in the Clouds: CircleCI
Author: Sergey Vasiliev, Ilya Gainulin
Date: 07.10.2019
Tags: Cpp, DevOps
This is a new piece of our series of articles about using the PVS-Studio static analyzer with cloud CI
systems. Today we are going to look at another service, CircleCI. We'll take the Kodi media player
application as a test project and see if we can find any interesting bugs in its source code.
Note. The previous articles on integrating PVS-Studio with cloud CI systems:
• PVS-Studio in the Clouds: Azure DevOps
• PVS-Studio in the Clouds - Running the Analysis on Travis CI
Before setting up the work environment and examining the analysis report, I'd like to say a few
words about the software we are going to use and check.
CircleCI is a cloud CI service for automated software building, testing, and deployment. It supports
project building both in containers and on virtual machines on Windows, Linux, and macOS.
Kodi is a free and open-source cross-platform media player application. It allows users to play and
view most streaming media, such as videos, music, podcasts, and videos from the Internet, as well as
all common digital media files from local and network storage media. It supports the use of themes
and skins and functionality extensions through plugins. Kodi is available for Windows, Linux, macOS,
and Android.
PVS-Studio is a static analyzer for detecting bugs and potential vulnerabilities in the source code of
applications written in C, C++, C#, and Java. The analyzer runs on Windows, Linux, and macOS.
Setting up
First we need to go to the CircleCI main page and click "Sign Up"
On the next page, we are offered to authorize with a GitHub or Bitbucket account. We choose
GitHub and get to the CircleCI authorization page.
After authorizing the application (by clicking the green button "Authorize circleci"), we are
redirected to the "Welcome to CircleCI!" page:
Here we can specify right away which projects we want CircleCI to build. We tick our repository and
click "Follow".
After adding the repository, CircleCI will automatically start the build process, but since we don't
have a configuration file in our repository yet, the build job will be aborted with an error message.
Before adding a configuration file, we need to add a couple of variables containing analyzer license
data. To do that, we click "Settings" on the left sidebar, select "Projects" in the "ORGANIZATION"
section, and click the cogwheel button to the right of our project's name. A settings window will
appear.
We go to the "Environment Variables" page. Here we create two variables, PVS_USERNAME and
PVS_KEY, which contain the username and analyzer license key.
When starting the build, CircleCI reads the job configuration from the file stored in the repository at
.circleci/config.yml. Let's add it.
First we need to specify the image of the virtual machine that the analyzer will be running on. The
complete list of images is available here.
version: 2
jobs:
build:
machine:
image: ubuntu-1604:201903-01
Next, we add the necessary repositories to apt and install the project's dependencies:
steps:
- checkout
- run: sudo -- sh -c "
add-apt-repository -y ppa:team-xbmc/xbmc-ppa-build-depends
&& add-apt-repository -y ppa:wsnipex/vaapi
&& add-apt-repository -y ppa:pulse-eight/libcec
&& apt-get update"
- run: sudo apt-get install -y
automake autopoint build-essential cmake
curl default-jre gawk gdb gdc gettext git-core
gperf libasound2-dev libass-dev libbluray-dev
libbz2-dev libcap-dev libcdio-dev libcec4-dev
libcrossguid-dev libcurl3 libcurl4-openssl-dev
libdbus-1-dev libegl1-mesa-dev libfmt3-dev
libfontconfig-dev libfreetype6-dev libfribidi-dev
libfstrcmp-dev libgif-dev libgl1-mesa-dev
libglu1-mesa-dev libiso9660-dev libjpeg-dev
liblcms2-dev libltdl-dev liblzo2-dev libmicrohttpd-dev
libmysqlclient-dev libnfs-dev libpcre3-dev libplist-dev
libpng-dev libpulse-dev libsmbclient-dev libsqlite3-dev
libssl-dev libtag1-dev libtinyxml-dev libtool libudev-dev
libusb-dev libva-dev libvdpau-dev libxml2-dev libxmu-dev
libxrandr-dev libxrender-dev libxslt1-dev libxt-dev
mesa-utils nasm pmount python-dev python-imaging
python-sqlite rapidjson-dev swig unzip uuid-dev yasm
zip zlib1g-dev wget
Adding the PVS-Studio repository and installing the analyzer:
- run: 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
- run: sudo -- sh -c "apt-get update
&& apt-get install pvs-studio -y"
Then we are building the dependencies:
- run: sudo make -C tools/depends/target/flatbuffers PREFIX=/usr/local
After that, we generate Makefiles in the build directory:
- run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug ..
The next step is setting up and starting an analysis of the project.
First we create an analyzer license file. Another command will start tracing the project build by the
compiler.
The next command following the tracing runs the analysis as such. If you use a demo version of PVS-
Studio, launch it with the parameter:
--disableLicenseExpirationCheck.
The final command converts the analyzer's report file into an html report:
- run: pvs-studio-analyzer credentials -o PVS.lic ${PVS_USER} ${PVS_KEY}
- run: pvs-studio-analyzer trace -- make -j2 -C build/
- run: pvs-studio-analyzer analyze -j2 -l PVS.lic
-o PVS-Studio.log --disableLicenseExpirationCheck
- run: plog-converter -t html -o PVS-Studio.html PVS-Studio.log
Once the tests are over, we save the reports:
- run: mkdir PVS_Result && cp PVS-Studio.* ./PVS_Result/
- store_artifacts:
path: ./PVS_Result
Here's the complete text of the .circleci/config.yml file:
version: 2.1
jobs:
build:
machine:
image: ubuntu-1604:201903-01
steps:
- checkout
- run: sudo -- sh -c "
add-apt-repository -y ppa:team-xbmc/xbmc-ppa-build-depends
&& add-apt-repository -y ppa:wsnipex/vaapi
&& add-apt-repository -y ppa:pulse-eight/libcec
&& apt-get update"
- run: sudo apt-get install -y automake autopoint
build-essential cmake curl default-jre gawk gdb
gdc gettext git-core gperf libasound2-dev libass-dev
libbluray-dev libbz2-dev libcap-dev libcdio-dev
libcec4-dev libcrossguid-dev libcurl3 libcurl4-openssl-dev
libdbus-1-dev libegl1-mesa-dev libfmt3-dev libfontconfig-dev
libfreetype6-dev libfribidi-dev libfstrcmp-dev libgif-dev
libgl1-mesa-dev libglu1-mesa-dev libiso9660-dev libjpeg-dev
liblcms2-dev libltdl-dev liblzo2-dev libmicrohttpd-dev
libmysqlclient-dev libnfs-dev libpcre3-dev libplist-dev
libpng-dev libpulse-dev libsmbclient-dev libsqlite3-dev
libssl-dev libtag1-dev libtinyxml-dev libtool libudev-dev
libusb-dev libva-dev libvdpau-dev libxml2-dev libxmu-dev
libxrandr-dev libxrender-dev libxslt1-dev libxt-dev mesa-utils
nasm pmount python-dev python-imaging python-sqlite
rapidjson-dev swig unzip uuid-dev yasm zip zlib1g-dev wget
- run: 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
- run: sudo -- sh -c "apt-get update && apt-get install pvs-studio -y"
- run: sudo make -C tools/depends/target/flatbuffers PREFIX=/usr/local
- run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug ..
- run: pvs-studio-analyzer credentials -o PVS.lic ${PVS_USER} ${PVS_KEY}
- run: pvs-studio-analyzer trace -- make -j2 -C build/
- run: pvs-studio-analyzer analyze -j2 -l PVS.lic
-o PVS-Studio.log --disableLicenseExpirationCheck
- run: plog-converter -t html -o PVS-Studio.html PVS-Studio.log
- run: mkdir PVS_Result && cp PVS-Studio.* ./PVS_Result/
- store_artifacts:
path: ./PVS_Result
Once this file is uploaded to the repository, CircleCI will automatically start the build.
Once the job is finished, the files with the analysis results can be downloaded on the "Artifacts" tab.
Analysis results
OK, now let's take a look at some of the warnings output by the analyzer.
PVS-Studio warning: V504 It is highly probable that the semicolon ';' is missing after 'return'
keyword. AdvancedSettings.cpp:1476
void CAdvancedSettings::SetExtraArtwork(const TiXmlElement* arttypes,
std::vector<std::string>& artworkMap)
{
if (!arttypes)
return
artworkMap.clear();
const TiXmlNode* arttype = arttypes->FirstChild("arttype");
....
}
The code formatting suggests the following execution logic:
• if arttypes is a null pointer, the method returns;
• if arttypes is a non-null pointer, the artworkMap vector gets cleared and some actions are
then performed.
But the missing ';' character breaks it all, and the actual execution logic is as follows:
• if arttypes is a null pointer, the artworkMap vector gets cleared and the method returns;
• if arttypes is a non-null pointer, the program executes whatever actions come next but the
artworkMap vector doesn't get cleared.
To cut a long story short, this situation does look like a bug. After all, you hardly expect anyone to
write expressions like return artworkMap.clear(); :).
PVS-Studio warnings:
• V547 Expression 'lastsector' is always false. udf25.cpp:636
• V547 Expression 'lastsector' is always false. udf25.cpp:644
• V571 Recurring check. The 'if (lastsector)' condition was already verified in line 636.
udf25.cpp:644
int udf25::UDFGetAVDP( struct avdp_t *avdp)
{
....
uint32_t lastsector;
....
lastsector = 0; // <=
....
for(;;) {
....
if( lastsector ) { // <= V547
lbnum = lastsector;
terminate = 1;
} else {
//! @todo Find last sector of the disc (this is optional).
if( lastsector ) // <= V547
lbnum = lastsector - 256;
else
return 0;
}
}
....
}
Note the spots marked with // <=. The lastsector variable is assigned the value 0 and then used as a
conditional expression in two if statements. Since the value doesn't change either in the loop or
between the assignments, control will never get into then branches of both if statements.
However, it could also mean that the developers simply haven't implemented the intended
functionality yet (note the @todo remark).
By the way, as you probably noticed, this snippet triggered three warnings at once. But even that
many warnings for one piece of code wouldn't look convincing enough to some users, and they
would keep believing that the analyzer is wrong... This aspect is discussed in detail in a post by one
of my teammates: "One Day from PVS-Studio User Support" :).
PVS-Studio warning: V547 Expression 'values.size() != 2' is always false.
GUIControlSettings.cpp:1174
bool CGUIControlRangeSetting::OnClick()
{
....
std::vector<CVariant> values;
SettingConstPtr listDefintion = settingList->GetDefinition();
switch (listDefintion->GetType())
{
case SettingType::Integer:
values.push_back(m_pSlider->
GetIntValue(CGUISliderControl::RangeSelectorLower));
values.push_back(m_pSlider->
GetIntValue(CGUISliderControl::RangeSelectorUpper));
break;
case SettingType::Number:
values.push_back(m_pSlider->
GetFloatValue(CGUISliderControl::RangeSelectorLower));
values.push_back(m_pSlider->
GetFloatValue(CGUISliderControl::RangeSelectorUpper));
break;
default:
return false;
}
if (values.size() != 2)
return false;
SetValid(CSettingUtils::SetList(settingList, values));
return IsValid();
}
The values.size() != 2 check is redundant here since this conditional expression will always evaluate
to false. Indeed, if execution enters one of the case branches of the switch statement, two elements
will be added to the vector, and since it was initially empty, its size will naturally become equal to 2;
otherwise (i.e. if the default branch is executed), the method will return.
PVS-Studio warning: V547 Expression 'prio == 0x7fffffff' is always true. DBusReserve.cpp:57
bool CDBusReserve::AcquireDevice(const std::string& device)
{
....
int prio = INT_MAX;
....
res =
dbus_bus_request_name(
m_conn,
service.c_str(),
DBUS_NAME_FLAG_DO_NOT_QUEUE |
(prio == INT_MAX ? 0 : DBUS_NAME_FLAG_ALLOW_REPLACEMENT), // <=
error);
....
}
The prio variable is initialized to the INT_MAX value and then used as an operand of the ternary
operator in the prio == INT_MAX comparison, though its value doesn't change after the initialization.
It means the prio == INT_MAX expression is true and the ternary operator will always return 0.
PVS-Studio warnings:
• V575 The potential null pointer is passed into 'memcpy' function. Inspect the first argument.
Check lines: 39, 38. DVDOverlayImage.h:39
• V575 The potential null pointer is passed into 'memcpy' function. Inspect the first argument.
Check lines: 44, 43. DVDOverlayImage.h:44
CDVDOverlayImage(const CDVDOverlayImage& src)
: CDVDOverlay(src)
{
Data = (uint8_t*)malloc(src.linesize * src.height);
memcpy(data, src.data, src.linesize * src.height); // <=
if(src.palette)
{
palette = (uint32_t*)malloc(src.palette_colors * 4);
memcpy(palette, src.palette, src.palette_colors * 4); // <=
}
....
}
Both warnings have the same pattern: a pointer returned by the malloc function is used further in
the memcpy function without being checked for NULL first.
Some may argue that malloc will never return a null pointer, and if it does, it would be better for the
application to crash. It's a subject of a separate discussion, but whatever your opinion is, I
recommend reading this post by my teammate: "Why it is important to check what the malloc
function returned".
If you wish, you can customize the analyzer so that it doesn't assume that malloc could return a null
pointer – this will keep it from outputting this type of warnings. More details can be found here.
PVS-Studio warning: V522 There might be dereferencing of a potential null pointer 'entry'. Check
lines: 985, 981. emu_msvcrt.cpp:985
struct dirent *dll_readdir(DIR *dirp)
{
....
struct dirent *entry = NULL;
entry = (dirent*) malloc(sizeof(*entry));
if (dirData->curr_index < dirData->items.Size() + 2)
{
if (dirData->curr_index == 0)
strncpy(entry->d_name, ".0", 2);
....
}
This example is similar to the previous one. The pointer returned by the malloc function is stored to
the entry variable, and this variable is then used without a prior null check (entry->d_name).
PVS-Studio warning: V773 Visibility scope of the 'progressHandler' pointer was exited without
releasing the memory. A memory leak is possible. PVRGUIChannelIconUpdater.cpp:94
void CPVRGUIChannelIconUpdater::SearchAndUpdateMissingChannelIcons() const
{
....
CPVRGUIProgressHandler* progressHandler =
new CPVRGUIProgressHandler(g_localizeStrings.Get(19286));
for (const auto& group : m_groups)
{
const std::vector<PVRChannelGroupMember> members = group->GetMembers();
int channelIndex = 0;
for (const auto& member : members)
{
progressHandler->UpdateProgress(member.channel->ChannelName(),
channelIndex++, members.size());
....
}
progressHandler->DestroyProgress();
}
The value of the progressHandler pointer was returned by the new operator. But there is no delete
operator for this pointer. This means a memory leak.
PVS-Studio warning: V557 Array overrun is possible. The 'idx' index is pointing beyond array bound.
PlayerCoreFactory.cpp:240
std::vector<CPlayerCoreConfig *> m_vecPlayerConfigs;
bool CPlayerCoreFactory::PlaysVideo(const std::string& player) const
{
CSingleLock lock(m_section);
size_t idx = GetPlayerIndex(player);
if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size())
return false;
return m_vecPlayerConfigs[idx]->m_bPlaysVideo;
}
The if statement restricts the m_vecPlayerConfigs vector's size to a certain range by having the
method return if the size-checking condition is true. As a result, when execution reaches the last
return statement, the m_vecPlayerConfigs vector's size will be within the specified range, [1; idx].
But a couple of lines later, the program is indexing the vector at idx: m_vecPlayerConfigs[idx]-
>m_bPlaysVideo. It means that if idx is equal to the vector's size, we'll be indexing beyond the valid
range.
Let's wind up this article with a couple of examples from the code of the Platinum library.
PVS-Studio warning: V542 Consider inspecting an odd type cast: 'bool' to 'char *'.
PltCtrlPoint.cpp:1617
NPT_Result PLT_CtrlPoint::ProcessSubscribeResponse(...)
{
....
bool subscription = (request.GetMethod().ToUppercase() == "SUBSCRIBE");
....
NPT_String prefix = NPT_String::Format("
PLT_CtrlPoint::ProcessSubscribeResponse %ubscribe for
service "%s" (result = %d, status code = %d)",
(const char*)subscription?"S":"Uns", // <=
(const char*)service->GetServiceID(),
res,
response?response->GetStatusCode():0);
....
}
The developers have had wrong assumptions about the operations' precedence. What gets cast to
const char* is not the result returned by the ternary operator (subscription ? "S" : "Uns") but the
subscription variable. This looks strange, at the very least.
PVS-Studio warning: V560 A part of conditional expression is always false: c == 't'. NptUtils.cpp:863
NPT_Result NPT_ParseMimeParameters(....)
{
....
case NPT_MIME_PARAMETER_PARSER_STATE_NEED_EQUALS:
if (c < ' ') return NPT_ERROR_INVALID_SYNTAX; // END or CTLs are invalid
if (c == ' ' || c == 't') continue; // ignore leading whitespace
....
}
The code of the space character is 0x20, and the code of the tab character is 0x09. Therefore, the c
== 't' subexpression will always evaluate to false as this case is already covered by the c < ' ' check
(which, if true, will cause the function to return).
Conclusion
As this article demonstrates, we successfully set up an analysis by PVS-Studio on yet another CI
system (CircleCI). I invite you to download and try the analyzer on your own project. If you have any
questions about the setting-up or use of PVS-Studio, don't hesitate to contact us – we'll be glad to
help.
And, of course, we wish you bugless code. :)

More Related Content

What's hot

Kubernetes: Learning from Zero to Production
Kubernetes: Learning from Zero to ProductionKubernetes: Learning from Zero to Production
Kubernetes: Learning from Zero to ProductionRosemary Wang
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Rajmahendra Hegde
 
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Evgeny Antyshev
 
How to integrate front end tool via gruntjs
How to integrate front end tool via gruntjsHow to integrate front end tool via gruntjs
How to integrate front end tool via gruntjsBo-Yi Wu
 
Использование Docker в CI / Александр Акбашев (HERE Technologies)
Использование Docker в CI / Александр Акбашев (HERE Technologies)Использование Docker в CI / Александр Акбашев (HERE Technologies)
Использование Docker в CI / Александр Акбашев (HERE Technologies)Ontico
 
Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new buildIgor Khotin
 
OpenDaylight Developer Experience 2.0
 OpenDaylight Developer Experience 2.0 OpenDaylight Developer Experience 2.0
OpenDaylight Developer Experience 2.0Michael Vorburger
 
Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceBo-Yi Wu
 
Nebula: Netflix's OSS Gradle Plugins
Nebula: Netflix's OSS Gradle PluginsNebula: Netflix's OSS Gradle Plugins
Nebula: Netflix's OSS Gradle PluginsRob Spieldenner
 
Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP applicationJavier López
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.Javier López
 
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...Puppet
 
Managing dependencies with gradle
Managing dependencies with gradleManaging dependencies with gradle
Managing dependencies with gradleLiviu Tudor
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins Mando Stam
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extremeyinonavraham
 
Aug penguin16
Aug penguin16Aug penguin16
Aug penguin16alhino
 

What's hot (20)

Kubernetes: Learning from Zero to Production
Kubernetes: Learning from Zero to ProductionKubernetes: Learning from Zero to Production
Kubernetes: Learning from Zero to Production
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
 
How to integrate front end tool via gruntjs
How to integrate front end tool via gruntjsHow to integrate front end tool via gruntjs
How to integrate front end tool via gruntjs
 
Использование Docker в CI / Александр Акбашев (HERE Technologies)
Использование Docker в CI / Александр Акбашев (HERE Technologies)Использование Docker в CI / Александр Акбашев (HERE Technologies)
Использование Docker в CI / Александр Акбашев (HERE Technologies)
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new build
 
OpenDaylight Developer Experience 2.0
 OpenDaylight Developer Experience 2.0 OpenDaylight Developer Experience 2.0
OpenDaylight Developer Experience 2.0
 
Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript Conference
 
Nebula: Netflix's OSS Gradle Plugins
Nebula: Netflix's OSS Gradle PluginsNebula: Netflix's OSS Gradle Plugins
Nebula: Netflix's OSS Gradle Plugins
 
Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP application
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.
 
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
 
Managing dependencies with gradle
Managing dependencies with gradleManaging dependencies with gradle
Managing dependencies with gradle
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
 
sed.pdf
sed.pdfsed.pdf
sed.pdf
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
 
Aug penguin16
Aug penguin16Aug penguin16
Aug penguin16
 

Similar to PVS-Studio in the Clouds: CircleCI

PVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIPVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIAndrey Karpov
 
Tutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of IndiaTutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of IndiaArun Ganesh
 
PVS-Studio in the Clouds: Azure DevOps
PVS-Studio in the Clouds: Azure DevOpsPVS-Studio in the Clouds: Azure DevOps
PVS-Studio in the Clouds: Azure DevOpsAndrey Karpov
 
Automate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon ViennaAutomate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon ViennaPantheon
 
Rasperry Pi and TI CC2650 IPv6 border router
Rasperry Pi and TI CC2650 IPv6 border routerRasperry Pi and TI CC2650 IPv6 border router
Rasperry Pi and TI CC2650 IPv6 border routerNikolaos Monios
 
Gitlab and Lingvokot
Gitlab and LingvokotGitlab and Lingvokot
Gitlab and LingvokotLingvokot
 
Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Andrey Karpov
 
Openshift cheat rhce_r3v1 rhce
Openshift cheat rhce_r3v1 rhceOpenshift cheat rhce_r3v1 rhce
Openshift cheat rhce_r3v1 rhceDarnette A
 
Serverless in production, an experience report (FullStack 2018)
Serverless in production, an experience report (FullStack 2018)Serverless in production, an experience report (FullStack 2018)
Serverless in production, an experience report (FullStack 2018)Yan Cui
 
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021whywaita
 
Exploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in PythonExploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in PythonIvan Ma
 
Serverless in Production, an experience report (AWS UG South Wales)
Serverless in Production, an experience report (AWS UG South Wales)Serverless in Production, an experience report (AWS UG South Wales)
Serverless in Production, an experience report (AWS UG South Wales)Yan Cui
 
Html5 devconf nodejs_devops_shubhra
Html5 devconf nodejs_devops_shubhraHtml5 devconf nodejs_devops_shubhra
Html5 devconf nodejs_devops_shubhraShubhra Kar
 
sfdx continuous Integration with Jenkins on aws (Part II)
sfdx continuous Integration with Jenkins on aws (Part II)sfdx continuous Integration with Jenkins on aws (Part II)
sfdx continuous Integration with Jenkins on aws (Part II)Jérémy Vial
 
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOps
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOpsMake stateful apps in Kubernetes a no brainer with Pure Storage and GitOps
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOpsWeaveworks
 
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...Amazon Web Services
 
Статический анализ кода в контексте SSDL
Статический анализ кода в контексте SSDLСтатический анализ кода в контексте SSDL
Статический анализ кода в контексте SSDLPositive Hack Days
 

Similar to PVS-Studio in the Clouds: CircleCI (20)

PVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIPVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CI
 
Tutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of IndiaTutorial to setup OpenStreetMap tileserver with customized boundaries of India
Tutorial to setup OpenStreetMap tileserver with customized boundaries of India
 
PVS-Studio in the Clouds: Azure DevOps
PVS-Studio in the Clouds: Azure DevOpsPVS-Studio in the Clouds: Azure DevOps
PVS-Studio in the Clouds: Azure DevOps
 
Automate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon ViennaAutomate Your Automation | DrupalCon Vienna
Automate Your Automation | DrupalCon Vienna
 
Rasperry Pi and TI CC2650 IPv6 border router
Rasperry Pi and TI CC2650 IPv6 border routerRasperry Pi and TI CC2650 IPv6 border router
Rasperry Pi and TI CC2650 IPv6 border router
 
Gitlab and Lingvokot
Gitlab and LingvokotGitlab and Lingvokot
Gitlab and Lingvokot
 
Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#
 
Openshift cheat rhce_r3v1 rhce
Openshift cheat rhce_r3v1 rhceOpenshift cheat rhce_r3v1 rhce
Openshift cheat rhce_r3v1 rhce
 
Serverless in production, an experience report (FullStack 2018)
Serverless in production, an experience report (FullStack 2018)Serverless in production, an experience report (FullStack 2018)
Serverless in production, an experience report (FullStack 2018)
 
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021
CyberAgent における OSS の CI/CD 基盤開発 myshoes #CICD2021
 
Exploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in PythonExploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in Python
 
Checking Bitcoin
 Checking Bitcoin Checking Bitcoin
Checking Bitcoin
 
Serverless in Production, an experience report (AWS UG South Wales)
Serverless in Production, an experience report (AWS UG South Wales)Serverless in Production, an experience report (AWS UG South Wales)
Serverless in Production, an experience report (AWS UG South Wales)
 
SAST_QSDL
SAST_QSDLSAST_QSDL
SAST_QSDL
 
Html5 devconf nodejs_devops_shubhra
Html5 devconf nodejs_devops_shubhraHtml5 devconf nodejs_devops_shubhra
Html5 devconf nodejs_devops_shubhra
 
Optimizing Your CI Pipelines
Optimizing Your CI PipelinesOptimizing Your CI Pipelines
Optimizing Your CI Pipelines
 
sfdx continuous Integration with Jenkins on aws (Part II)
sfdx continuous Integration with Jenkins on aws (Part II)sfdx continuous Integration with Jenkins on aws (Part II)
sfdx continuous Integration with Jenkins on aws (Part II)
 
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOps
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOpsMake stateful apps in Kubernetes a no brainer with Pure Storage and GitOps
Make stateful apps in Kubernetes a no brainer with Pure Storage and GitOps
 
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...
(ARC402) Deployment Automation: From Developers' Keyboards to End Users' Scre...
 
Статический анализ кода в контексте SSDL
Статический анализ кода в контексте SSDLСтатический анализ кода в контексте SSDL
Статический анализ кода в контексте SSDL
 

More from Andrey Karpov

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программистаAndrey Karpov
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developerAndrey Karpov
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Andrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewAndrey Karpov
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Andrey Karpov
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?Andrey Karpov
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaAndrey Karpov
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)Andrey Karpov
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Andrey Karpov
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareAndrey Karpov
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineAndrey Karpov
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsAndrey Karpov
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++Andrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youAndrey Karpov
 

More from Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Recently uploaded

Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 

Recently uploaded (20)

Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 

PVS-Studio in the Clouds: CircleCI

  • 1. PVS-Studio in the Clouds: CircleCI Author: Sergey Vasiliev, Ilya Gainulin Date: 07.10.2019 Tags: Cpp, DevOps This is a new piece of our series of articles about using the PVS-Studio static analyzer with cloud CI systems. Today we are going to look at another service, CircleCI. We'll take the Kodi media player application as a test project and see if we can find any interesting bugs in its source code. Note. The previous articles on integrating PVS-Studio with cloud CI systems: • PVS-Studio in the Clouds: Azure DevOps • PVS-Studio in the Clouds - Running the Analysis on Travis CI Before setting up the work environment and examining the analysis report, I'd like to say a few words about the software we are going to use and check. CircleCI is a cloud CI service for automated software building, testing, and deployment. It supports project building both in containers and on virtual machines on Windows, Linux, and macOS.
  • 2. Kodi is a free and open-source cross-platform media player application. It allows users to play and view most streaming media, such as videos, music, podcasts, and videos from the Internet, as well as all common digital media files from local and network storage media. It supports the use of themes and skins and functionality extensions through plugins. Kodi is available for Windows, Linux, macOS, and Android. PVS-Studio is a static analyzer for detecting bugs and potential vulnerabilities in the source code of applications written in C, C++, C#, and Java. The analyzer runs on Windows, Linux, and macOS. Setting up First we need to go to the CircleCI main page and click "Sign Up" On the next page, we are offered to authorize with a GitHub or Bitbucket account. We choose GitHub and get to the CircleCI authorization page.
  • 3. After authorizing the application (by clicking the green button "Authorize circleci"), we are redirected to the "Welcome to CircleCI!" page: Here we can specify right away which projects we want CircleCI to build. We tick our repository and click "Follow". After adding the repository, CircleCI will automatically start the build process, but since we don't have a configuration file in our repository yet, the build job will be aborted with an error message.
  • 4. Before adding a configuration file, we need to add a couple of variables containing analyzer license data. To do that, we click "Settings" on the left sidebar, select "Projects" in the "ORGANIZATION" section, and click the cogwheel button to the right of our project's name. A settings window will appear. We go to the "Environment Variables" page. Here we create two variables, PVS_USERNAME and PVS_KEY, which contain the username and analyzer license key.
  • 5. When starting the build, CircleCI reads the job configuration from the file stored in the repository at .circleci/config.yml. Let's add it. First we need to specify the image of the virtual machine that the analyzer will be running on. The complete list of images is available here. version: 2 jobs: build: machine: image: ubuntu-1604:201903-01 Next, we add the necessary repositories to apt and install the project's dependencies: steps: - checkout - run: sudo -- sh -c " add-apt-repository -y ppa:team-xbmc/xbmc-ppa-build-depends && add-apt-repository -y ppa:wsnipex/vaapi && add-apt-repository -y ppa:pulse-eight/libcec && apt-get update" - run: sudo apt-get install -y automake autopoint build-essential cmake curl default-jre gawk gdb gdc gettext git-core gperf libasound2-dev libass-dev libbluray-dev libbz2-dev libcap-dev libcdio-dev libcec4-dev libcrossguid-dev libcurl3 libcurl4-openssl-dev libdbus-1-dev libegl1-mesa-dev libfmt3-dev libfontconfig-dev libfreetype6-dev libfribidi-dev libfstrcmp-dev libgif-dev libgl1-mesa-dev libglu1-mesa-dev libiso9660-dev libjpeg-dev liblcms2-dev libltdl-dev liblzo2-dev libmicrohttpd-dev libmysqlclient-dev libnfs-dev libpcre3-dev libplist-dev libpng-dev libpulse-dev libsmbclient-dev libsqlite3-dev libssl-dev libtag1-dev libtinyxml-dev libtool libudev-dev
  • 6. libusb-dev libva-dev libvdpau-dev libxml2-dev libxmu-dev libxrandr-dev libxrender-dev libxslt1-dev libxt-dev mesa-utils nasm pmount python-dev python-imaging python-sqlite rapidjson-dev swig unzip uuid-dev yasm zip zlib1g-dev wget Adding the PVS-Studio repository and installing the analyzer: - run: 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 - run: sudo -- sh -c "apt-get update && apt-get install pvs-studio -y" Then we are building the dependencies: - run: sudo make -C tools/depends/target/flatbuffers PREFIX=/usr/local After that, we generate Makefiles in the build directory: - run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. The next step is setting up and starting an analysis of the project. First we create an analyzer license file. Another command will start tracing the project build by the compiler. The next command following the tracing runs the analysis as such. If you use a demo version of PVS- Studio, launch it with the parameter: --disableLicenseExpirationCheck. The final command converts the analyzer's report file into an html report: - run: pvs-studio-analyzer credentials -o PVS.lic ${PVS_USER} ${PVS_KEY} - run: pvs-studio-analyzer trace -- make -j2 -C build/ - run: pvs-studio-analyzer analyze -j2 -l PVS.lic -o PVS-Studio.log --disableLicenseExpirationCheck - run: plog-converter -t html -o PVS-Studio.html PVS-Studio.log Once the tests are over, we save the reports: - run: mkdir PVS_Result && cp PVS-Studio.* ./PVS_Result/ - store_artifacts: path: ./PVS_Result Here's the complete text of the .circleci/config.yml file: version: 2.1 jobs: build: machine:
  • 7. image: ubuntu-1604:201903-01 steps: - checkout - run: sudo -- sh -c " add-apt-repository -y ppa:team-xbmc/xbmc-ppa-build-depends && add-apt-repository -y ppa:wsnipex/vaapi && add-apt-repository -y ppa:pulse-eight/libcec && apt-get update" - run: sudo apt-get install -y automake autopoint build-essential cmake curl default-jre gawk gdb gdc gettext git-core gperf libasound2-dev libass-dev libbluray-dev libbz2-dev libcap-dev libcdio-dev libcec4-dev libcrossguid-dev libcurl3 libcurl4-openssl-dev libdbus-1-dev libegl1-mesa-dev libfmt3-dev libfontconfig-dev libfreetype6-dev libfribidi-dev libfstrcmp-dev libgif-dev libgl1-mesa-dev libglu1-mesa-dev libiso9660-dev libjpeg-dev liblcms2-dev libltdl-dev liblzo2-dev libmicrohttpd-dev libmysqlclient-dev libnfs-dev libpcre3-dev libplist-dev libpng-dev libpulse-dev libsmbclient-dev libsqlite3-dev libssl-dev libtag1-dev libtinyxml-dev libtool libudev-dev libusb-dev libva-dev libvdpau-dev libxml2-dev libxmu-dev libxrandr-dev libxrender-dev libxslt1-dev libxt-dev mesa-utils nasm pmount python-dev python-imaging python-sqlite rapidjson-dev swig unzip uuid-dev yasm zip zlib1g-dev wget - run: 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 - run: sudo -- sh -c "apt-get update && apt-get install pvs-studio -y" - run: sudo make -C tools/depends/target/flatbuffers PREFIX=/usr/local - run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. - run: pvs-studio-analyzer credentials -o PVS.lic ${PVS_USER} ${PVS_KEY} - run: pvs-studio-analyzer trace -- make -j2 -C build/ - run: pvs-studio-analyzer analyze -j2 -l PVS.lic -o PVS-Studio.log --disableLicenseExpirationCheck - run: plog-converter -t html -o PVS-Studio.html PVS-Studio.log - run: mkdir PVS_Result && cp PVS-Studio.* ./PVS_Result/ - store_artifacts:
  • 8. path: ./PVS_Result Once this file is uploaded to the repository, CircleCI will automatically start the build. Once the job is finished, the files with the analysis results can be downloaded on the "Artifacts" tab.
  • 9. Analysis results OK, now let's take a look at some of the warnings output by the analyzer. PVS-Studio warning: V504 It is highly probable that the semicolon ';' is missing after 'return' keyword. AdvancedSettings.cpp:1476 void CAdvancedSettings::SetExtraArtwork(const TiXmlElement* arttypes, std::vector<std::string>& artworkMap) { if (!arttypes) return artworkMap.clear(); const TiXmlNode* arttype = arttypes->FirstChild("arttype"); .... } The code formatting suggests the following execution logic: • if arttypes is a null pointer, the method returns; • if arttypes is a non-null pointer, the artworkMap vector gets cleared and some actions are then performed. But the missing ';' character breaks it all, and the actual execution logic is as follows: • if arttypes is a null pointer, the artworkMap vector gets cleared and the method returns; • if arttypes is a non-null pointer, the program executes whatever actions come next but the artworkMap vector doesn't get cleared. To cut a long story short, this situation does look like a bug. After all, you hardly expect anyone to write expressions like return artworkMap.clear(); :). PVS-Studio warnings: • V547 Expression 'lastsector' is always false. udf25.cpp:636 • V547 Expression 'lastsector' is always false. udf25.cpp:644 • V571 Recurring check. The 'if (lastsector)' condition was already verified in line 636. udf25.cpp:644 int udf25::UDFGetAVDP( struct avdp_t *avdp) { .... uint32_t lastsector; .... lastsector = 0; // <= .... for(;;) { .... if( lastsector ) { // <= V547 lbnum = lastsector; terminate = 1; } else { //! @todo Find last sector of the disc (this is optional). if( lastsector ) // <= V547 lbnum = lastsector - 256; else return 0; } } .... }
  • 10. Note the spots marked with // <=. The lastsector variable is assigned the value 0 and then used as a conditional expression in two if statements. Since the value doesn't change either in the loop or between the assignments, control will never get into then branches of both if statements. However, it could also mean that the developers simply haven't implemented the intended functionality yet (note the @todo remark). By the way, as you probably noticed, this snippet triggered three warnings at once. But even that many warnings for one piece of code wouldn't look convincing enough to some users, and they would keep believing that the analyzer is wrong... This aspect is discussed in detail in a post by one of my teammates: "One Day from PVS-Studio User Support" :). PVS-Studio warning: V547 Expression 'values.size() != 2' is always false. GUIControlSettings.cpp:1174 bool CGUIControlRangeSetting::OnClick() { .... std::vector<CVariant> values; SettingConstPtr listDefintion = settingList->GetDefinition(); switch (listDefintion->GetType()) { case SettingType::Integer: values.push_back(m_pSlider-> GetIntValue(CGUISliderControl::RangeSelectorLower)); values.push_back(m_pSlider-> GetIntValue(CGUISliderControl::RangeSelectorUpper)); break; case SettingType::Number: values.push_back(m_pSlider-> GetFloatValue(CGUISliderControl::RangeSelectorLower)); values.push_back(m_pSlider-> GetFloatValue(CGUISliderControl::RangeSelectorUpper)); break; default: return false; } if (values.size() != 2) return false; SetValid(CSettingUtils::SetList(settingList, values)); return IsValid(); } The values.size() != 2 check is redundant here since this conditional expression will always evaluate to false. Indeed, if execution enters one of the case branches of the switch statement, two elements will be added to the vector, and since it was initially empty, its size will naturally become equal to 2; otherwise (i.e. if the default branch is executed), the method will return. PVS-Studio warning: V547 Expression 'prio == 0x7fffffff' is always true. DBusReserve.cpp:57 bool CDBusReserve::AcquireDevice(const std::string& device) { .... int prio = INT_MAX; .... res = dbus_bus_request_name( m_conn, service.c_str(), DBUS_NAME_FLAG_DO_NOT_QUEUE | (prio == INT_MAX ? 0 : DBUS_NAME_FLAG_ALLOW_REPLACEMENT), // <= error); ....
  • 11. } The prio variable is initialized to the INT_MAX value and then used as an operand of the ternary operator in the prio == INT_MAX comparison, though its value doesn't change after the initialization. It means the prio == INT_MAX expression is true and the ternary operator will always return 0. PVS-Studio warnings: • V575 The potential null pointer is passed into 'memcpy' function. Inspect the first argument. Check lines: 39, 38. DVDOverlayImage.h:39 • V575 The potential null pointer is passed into 'memcpy' function. Inspect the first argument. Check lines: 44, 43. DVDOverlayImage.h:44 CDVDOverlayImage(const CDVDOverlayImage& src) : CDVDOverlay(src) { Data = (uint8_t*)malloc(src.linesize * src.height); memcpy(data, src.data, src.linesize * src.height); // <= if(src.palette) { palette = (uint32_t*)malloc(src.palette_colors * 4); memcpy(palette, src.palette, src.palette_colors * 4); // <= } .... } Both warnings have the same pattern: a pointer returned by the malloc function is used further in the memcpy function without being checked for NULL first. Some may argue that malloc will never return a null pointer, and if it does, it would be better for the application to crash. It's a subject of a separate discussion, but whatever your opinion is, I recommend reading this post by my teammate: "Why it is important to check what the malloc function returned". If you wish, you can customize the analyzer so that it doesn't assume that malloc could return a null pointer – this will keep it from outputting this type of warnings. More details can be found here. PVS-Studio warning: V522 There might be dereferencing of a potential null pointer 'entry'. Check lines: 985, 981. emu_msvcrt.cpp:985 struct dirent *dll_readdir(DIR *dirp) { .... struct dirent *entry = NULL; entry = (dirent*) malloc(sizeof(*entry)); if (dirData->curr_index < dirData->items.Size() + 2) { if (dirData->curr_index == 0) strncpy(entry->d_name, ".0", 2); .... } This example is similar to the previous one. The pointer returned by the malloc function is stored to the entry variable, and this variable is then used without a prior null check (entry->d_name). PVS-Studio warning: V773 Visibility scope of the 'progressHandler' pointer was exited without releasing the memory. A memory leak is possible. PVRGUIChannelIconUpdater.cpp:94 void CPVRGUIChannelIconUpdater::SearchAndUpdateMissingChannelIcons() const {
  • 12. .... CPVRGUIProgressHandler* progressHandler = new CPVRGUIProgressHandler(g_localizeStrings.Get(19286)); for (const auto& group : m_groups) { const std::vector<PVRChannelGroupMember> members = group->GetMembers(); int channelIndex = 0; for (const auto& member : members) { progressHandler->UpdateProgress(member.channel->ChannelName(), channelIndex++, members.size()); .... } progressHandler->DestroyProgress(); } The value of the progressHandler pointer was returned by the new operator. But there is no delete operator for this pointer. This means a memory leak. PVS-Studio warning: V557 Array overrun is possible. The 'idx' index is pointing beyond array bound. PlayerCoreFactory.cpp:240 std::vector<CPlayerCoreConfig *> m_vecPlayerConfigs; bool CPlayerCoreFactory::PlaysVideo(const std::string& player) const { CSingleLock lock(m_section); size_t idx = GetPlayerIndex(player); if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size()) return false; return m_vecPlayerConfigs[idx]->m_bPlaysVideo; } The if statement restricts the m_vecPlayerConfigs vector's size to a certain range by having the method return if the size-checking condition is true. As a result, when execution reaches the last return statement, the m_vecPlayerConfigs vector's size will be within the specified range, [1; idx]. But a couple of lines later, the program is indexing the vector at idx: m_vecPlayerConfigs[idx]- >m_bPlaysVideo. It means that if idx is equal to the vector's size, we'll be indexing beyond the valid range. Let's wind up this article with a couple of examples from the code of the Platinum library. PVS-Studio warning: V542 Consider inspecting an odd type cast: 'bool' to 'char *'. PltCtrlPoint.cpp:1617 NPT_Result PLT_CtrlPoint::ProcessSubscribeResponse(...) { .... bool subscription = (request.GetMethod().ToUppercase() == "SUBSCRIBE"); .... NPT_String prefix = NPT_String::Format(" PLT_CtrlPoint::ProcessSubscribeResponse %ubscribe for service "%s" (result = %d, status code = %d)", (const char*)subscription?"S":"Uns", // <= (const char*)service->GetServiceID(), res, response?response->GetStatusCode():0); .... }
  • 13. The developers have had wrong assumptions about the operations' precedence. What gets cast to const char* is not the result returned by the ternary operator (subscription ? "S" : "Uns") but the subscription variable. This looks strange, at the very least. PVS-Studio warning: V560 A part of conditional expression is always false: c == 't'. NptUtils.cpp:863 NPT_Result NPT_ParseMimeParameters(....) { .... case NPT_MIME_PARAMETER_PARSER_STATE_NEED_EQUALS: if (c < ' ') return NPT_ERROR_INVALID_SYNTAX; // END or CTLs are invalid if (c == ' ' || c == 't') continue; // ignore leading whitespace .... } The code of the space character is 0x20, and the code of the tab character is 0x09. Therefore, the c == 't' subexpression will always evaluate to false as this case is already covered by the c < ' ' check (which, if true, will cause the function to return). Conclusion As this article demonstrates, we successfully set up an analysis by PVS-Studio on yet another CI system (CircleCI). I invite you to download and try the analyzer on your own project. If you have any questions about the setting-up or use of PVS-Studio, don't hesitate to contact us – we'll be glad to help. And, of course, we wish you bugless code. :)