
Wieħed mill-aktar xenarji attwali għall-użu tal-analizzatur PVS-Studio huwa l-integrazzjoni tiegħu mas-sistemi CI. U għalkemm l-analiżi ta 'proġett PVS-Studio minn kważi kull sistema ta' integrazzjoni kontinwa tista 'tinbena fi ftit kmandi biss, aħna nkomplu nagħmlu dan il-proċess saħansitra aktar konvenjenti. PVS-Studio issa għandu appoġġ għall-konverżjoni tal-output tal-analizzatur f'format għal TeamCity - TeamCity Spezzjonijiet Tip. Ejja naraw kif taħdem.
Informazzjoni dwar is-softwer użat
— analizzatur statiku għall-kodiċi C, C++, C#, u Java, iddisinjat biex jiffaċilita l-kompitu li jinstabu u jiġu rranġati diversi tipi ta' żbalji. L-analizzatur jista' jintuża f' Windows, Linux и macOSF'dan l-artikolu, se nużaw b'mod attiv mhux biss l-analizzatur innifsu, iżda wkoll xi utilitajiet mid-distribuzzjoni tiegħu.
— huwa server ta' monitoraġġ li jimmonitorja t-tnedija tal-kompilaturi. Għandu jitmexxa immedjatament qabel ma tibda tibni l-proġett tiegħek. Fil-modalità snooping, is-server se jinterċetta ġirjiet tal-kompilaturi kollha appoġġjati. Ta 'min jinnota li din l-utilità tista' tintuża biss biex tanalizza proġetti C/C++.
– utilità għall-konverżjoni tar-rapporti tal-analizzaturi f'formati differenti.
Informazzjoni dwar il-proġett taħt studju
Ejja nippruvaw din il-funzjonalità fuq eżempju prattiku - ejja nanalizzaw il-proġett OpenRCT2.
- implimentazzjoni miftuħa tal-logħba RollerCoaster Tycoon 2 (RCT2), tespandiha b'funzjonijiet ġodda u tiffissa bugs. Il-logħba ddur madwar il-bini u ż-żamma ta' park tad-divertiment li jkun fih karozzini, ħwienet u faċilitajiet. Il-plejer irid jipprova jagħmel profitt u jżomm ir-reputazzjoni tajba tal-park filwaqt li jżomm lill-mistednin kuntenti. OpenRCT2 jippermettilek tilgħab kemm fix-xenarju kif ukoll f'sandbox. Xenarji jirrikjedu li l-plejer iwettaq kompitu speċifiku fi żmien stabbilit, filwaqt li Sandbox jippermetti lill-plejer jibni park aktar flessibbli mingħajr ebda restrizzjoni jew finanzi.
aġġustament
Sabiex niffranka l-ħin, probabbilment se naqbeż il-proċess ta 'installazzjoni u nibda mill-mument meta jkolli s-server TeamCity jaħdem fuq il-kompjuter tiegħi. Irridu mmorru għal: localhost:{port speċifikat matul il-proċess ta' installazzjoni} (fil-każ tiegħi, localhost:9090) u daħħal id-dejta tal-awtorizzazzjoni. Wara li nidħlu niġu milqugħa minn:

Ikklikkja fuq il-buttuna Oħloq Proġett. Sussegwentement, agħżel Manwalment u imla l-oqsma.

Wara li tagħfas il-buttuna Oħloq, aħna milqugħa minn tieqa b'settings.

Ejja ikklikkja Oħloq konfigurazzjoni tal-bini.

Imla l-oqsma u kklikkja Oħloq. Naraw tieqa titlobek tagħżel sistema ta 'kontroll tal-verżjoni. Peress li s-sorsi diġà jinsabu lokalment, ikklikkja Aqbeż.

Fl-aħħarnett, nimxu fuq is-settings tal-proġett.

Ejja nżidu l-passi tal-assemblaġġ, biex nagħmlu dan ikklikkja: Ibni passi -> Żid il-pass tal-bini.

Hawnhekk nagħżlu:
- Tip ta' runner -> Linja tal-Kmand
- Mexxi -> Custom Script
Peress li aħna se nwettqu analiżi waqt il-kumpilazzjoni tal-proġett, l-assemblaġġ u l-analiżi għandhom ikunu pass wieħed, għalhekk imla l-qasam Skript Custom:

Se nħarsu lejn passi individwali aktar tard. Huwa importanti li t-tagħbija tal-analizzatur, l-assemblaġġ tal-proġett, l-analiżi tiegħu, il-ħruġ tar-rapport u l-ifformattjar jieħu biss ħdax-il linja ta 'kodiċi.
L-aħħar ħaġa li rridu nagħmlu hija li nissettjaw il-varjabbli ambjentali, li stajt spjegajt xi modi kif intejbu l-leġibbiltà tagħhom. Biex tagħmel dan, ejja nkomplu: Parametri -> Żid parametru ġdid u żid tliet varjabbli:

Kull ma trid tagħmel hu li tagħfas il-buttuna Mexxi fir-rokna ta’ fuq tal-lemin. Waqt li l-proġett qed jiġi mmuntat u analizzat, jien ngħidlek dwar l-iskript.
Direttament b'kitba
L-ewwel, għandna bżonn tniżżel l-aħħar distribuzzjoni PVS-Studio. Għal dan nużaw il-maniġer tal-pakketti Chocolatey. Għal dawk li jridu jkunu jafu aktar dwar dan, hemm korrispondenti :
choco install pvs-studio -ySussegwentement, ejja nniedu l-utilità ta 'traċċar tal-bini tal-proġett CLMonitor.
%CLmon% monitor –-attachImbagħad se nibnu l-proġett bħala varjabbli ambjentali MSB hija t-triq għall-verżjoni tal-MSBuild li għandi bżonn nibni
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortableEjja daħħal il-login u ċ-ċavetta tal-liċenzja għal PVS-Studio:
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%Wara li titlesta l-bini, erġa ħaddem CLMonitor biex tiġġenera fajls ipproċessati minn qabel u analiżi statika:
%CLmon% analyze -l "c:ptest.plog"Imbagħad se nużaw utilità oħra mid-distribuzzjoni tagħna. PlogConverter jikkonverti rapport minn format standard għal format speċifiku għal TeamCity. Grazzi għal dan, inkunu nistgħu narawha direttament fit-tieqa tal-bini.
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"L-aħħar pass huwa li turi r-rapport ifformattjat fi stdout, fejn se jinġabar mill-parser ta' TeamCity.
type "C:tempptest.plog_TeamCity.txt"Kodiċi tal-iskript sħiħ:
choco install pvs-studio -y
%CLmon% monitor --attach
set platform=x64
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
%CLmon% analyze -l "c:ptest.plog"
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
type "C:tempptest.plog_TeamCity.txt"Sadanittant, l-assemblaġġ u l-analiżi tal-proġett tlestiet b'suċċess, nistgħu mmorru fit-tab proġetti u kun żgur minnha.

Issa ejja ikklikkja fuq Spezzjonijiet Totalbiex tmur tara r-rapport tal-analizzatur:

It-twissijiet huma miġbura skond in-numri tar-regoli dijanjostiċi. Biex tinnaviga permezz tal-kodiċi, trid tikklikkja fuq in-numru tal-linja bit-twissija. Meta tikklikkja fuq il-marka tal-mistoqsija fir-rokna ta' fuq tal-lemin tiftaħlek tab ġdida bid-dokumentazzjoni. Tista 'wkoll tinnaviga permezz tal-kodiċi billi tikklikkja fuq in-numru tal-linja bit-twissija tal-analizzatur. In-navigazzjoni minn kompjuter remot hija possibbli meta tuża SourceTreeRoot markatur. Kull min huwa interessat f'dan il-mod ta 'tħaddim tal-analizzatur jista' jiffamiljarizza ruħu mat-taqsima korrispondenti .
Ara r-riżultati tal-analizzatur
Issa li lestejna l-iskjerament u l-konfigurazzjoni tal-bini, ejja nagħtu ħarsa lejn xi twissijiet interessanti misjuba fil-proġett li qed inħarsu lejh.
Twissija N1
[CWE-401] L-eċċezzjoni ġiet mitfugħa mingħajr ma ħarġet il-pointer tar-'riżultat'. Tnixxija tal-memorja hija possibbli. libopenrct2 ObjectFactory.cpp 443
Object* CreateObjectFromJson(....)
{
Object* result = nullptr;
....
result = CreateObject(entry);
....
if (readContext.WasError())
{
throw std::runtime_error("Object has errors");
}
....
}
Object* CreateObject(const rct_object_entry& entry)
{
Object* result;
switch (entry.GetType())
{
case OBJECT_TYPE_RIDE:
result = new RideObject(entry);
break;
case OBJECT_TYPE_SMALL_SCENERY:
result = new SmallSceneryObject(entry);
break;
case OBJECT_TYPE_LARGE_SCENERY:
result = new LargeSceneryObject(entry);
break;
....
default:
throw std::runtime_error("Invalid object type");
}
return result;
}L-analizzatur innota żball li wara li alloka b'mod dinamiku l-memorja Oħloq Oġġett, meta sseħħ eċċezzjoni, il-memorja ma titnaddafx, u sseħħ tnixxija tal-memorja.
Twissija N2
Hemm subespressjonijiet identiċi '(1ULL << WIDX_MONTH_BOX)' fuq ix-xellug u fuq il-lemin tal-'|' operatur. libopenrct2ui Cheats.cpp 487
static uint64_t window_cheats_page_enabled_widgets[] =
{
MAIN_CHEAT_ENABLED_WIDGETS |
(1ULL << WIDX_NO_MONEY) |
(1ULL << WIDX_ADD_SET_MONEY_GROUP) |
(1ULL << WIDX_MONEY_SPINNER) |
(1ULL << WIDX_MONEY_SPINNER_INCREMENT) |
(1ULL << WIDX_MONEY_SPINNER_DECREMENT) |
(1ULL << WIDX_ADD_MONEY) |
(1ULL << WIDX_SET_MONEY) |
(1ULL << WIDX_CLEAR_LOAN) |
(1ULL << WIDX_DATE_SET) |
(1ULL << WIDX_MONTH_BOX) | // <=
(1ULL << WIDX_MONTH_UP) |
(1ULL << WIDX_MONTH_DOWN) |
(1ULL << WIDX_YEAR_BOX) |
(1ULL << WIDX_YEAR_UP) |
(1ULL << WIDX_YEAR_DOWN) |
(1ULL << WIDX_DAY_BOX) |
(1ULL << WIDX_DAY_UP) |
(1ULL << WIDX_DAY_DOWN) |
(1ULL << WIDX_MONTH_BOX) | // <=
(1ULL << WIDX_DATE_GROUP) |
(1ULL << WIDX_DATE_RESET),
....
};Ftit nies minbarra analizzatur statiku jistgħu jgħaddu minn dan it-test ta 'attenzjoni. Dan l-eżempju copy-paste huwa tajjeb preċiżament għal din ir-raġuni.
Twissijiet N3
Huwa stramb li l-qasam 'bnadar' fil-klassi derivata 'RCT12BannerElement' jissostitwixxi l-qasam fil-klassi bażi 'RCT12TileElementBase'. Iċċekkja linji: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};Naturalment, l-użu ta 'varjabbli bl-istess isem fil-klassi bażi u fid-dixxendent mhux dejjem huwa żball. Madankollu, it-teknoloġija tal-wirt nnifisha tassumi li l-oqsma kollha tal-klassi ġenitur huma preżenti fil-klassi tifel. Billi niddikjaraw oqsma bl-istess isem fil-werriet, noħolqu konfużjoni.
Twissija N4
Huwa stramb li r-riżultat tad-dikjarazzjoni 'imageDirection / 8' huwa parti mill-kundizzjoni. Forsi, din id-dikjarazzjoni kellha tiġi mqabbla ma 'xi ħaġa oħra. libopenrct2 ObservationTower.cpp 38
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}Ejja nagħtu ħarsa aktar mill-qrib. Espressjoni imageDirection/8 se jkun falz jekk imageDirection hija fil-medda minn -7 sa 7. It-tieni parti: (Direzzjoni tal-immaġni / 8) != 3 kontrolli imageDirection talli tkun barra mill-medda: minn -31 sa -24 u minn 24 sa 31, rispettivament. Jidhirli pjuttost stramba li niċċekkja n-numri għall-inklużjoni f'ċerta firxa b'dan il-mod u, anke jekk ma jkun hemm l-ebda żball f'din il-biċċa tal-kodiċi, nirrakkomanda li nikteb mill-ġdid dawn il-kundizzjonijiet biex tkun aktar espliċita. Dan jagħmel il-ħajja ħafna aktar faċli għan-nies li jaqraw u jżommu dan il-kodiċi.
Twissija N5
Sekwenza fard ta' assenjazzjonijiet ta' dan it-tip: A = B; B = A;. Iċċekkja linji: 1115, 1118. libopenrct2ui MouseInput.cpp 1118
void process_mouse_over(....)
{
....
switch (window->widgets[widgetId].type)
{
case WWT_VIEWPORT:
ebx = 0;
edi = cursorId; // <=
// Window event WE_UNKNOWN_0E was called here,
// but no windows actually implemented a handler and
// it's not known what it was for
cursorId = edi; // <=
if ((ebx & 0xFF) != 0)
{
set_cursor(cursorId);
return;
}
break;
....
}
....
}Dan il-framment tal-kodiċi x'aktarx inkiseb permezz ta' dekompilazzjoni. Imbagħad, meta wieħed jiġġudika mill-kumment li jitħalla, tneħħiet parti mill-kodiċi li ma taħdemx. Madankollu, għad fadal ftit operazzjonijiet cursorId, li wkoll ma tantx jagħmlu sens.
Twissija N6
[CWE-476] Il-pointer tal-'player' intuża b'mod mhux sikur wara li ġie vverifikat kontra nullptr. Iċċekkja linji: 2085, 2094. libopenrct2 Network.cpp 2094
void Network::ProcessPlayerList()
{
....
auto* player = GetPlayerByID(pendingPlayer.Id);
if (player == nullptr)
{
// Add new player.
player = AddPlayer("", "");
if (player) // <=
{
*player = pendingPlayer;
if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
{
_serverConnection->Player = player;
}
}
newPlayers.push_back(player->Id); // <=
}
....
}Dan il-kodiċi huwa pjuttost faċli biex tikkoreġi; attur għal pointer null, jew żidha mal-korp tad-dikjarazzjoni kondizzjonali. Nissuġġerixxi t-tieni għażla:
void Network::ProcessPlayerList()
{
....
auto* player = GetPlayerByID(pendingPlayer.Id);
if (player == nullptr)
{
// Add new player.
player = AddPlayer("", "");
if (player)
{
*player = pendingPlayer;
if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
{
_serverConnection->Player = player;
}
newPlayers.push_back(player->Id);
}
}
....
}Twissija N7
[CWE-570] L-espressjoni 'name == nullptr' hija dejjem falza. libopenrct2 ServerList.cpp 102
std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
auto name = json_object_get(server, "name");
.....
if (name == nullptr || version == nullptr)
{
....
}
else
{
....
entry.name = (name == nullptr ? "" : json_string_value(name));
....
}
....
}Tista 'teħles minn linja ta' kodiċi diffiċli biex tinqara f'daqqa waħda u ssolvi l-problema bil-verifika għal nullptr. Nissuġġerixxi li tinbidel il-kodiċi kif ġej:
std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
auto name = json_object_get(server, "name");
.....
if (name == nullptr || version == nullptr)
{
name = ""
....
}
else
{
....
entry.name = json_string_value(name);
....
}
....
}Twissija N8
[CWE-1164] Il-varjabbli 'ColumnHeaderPressedCurrentState' ġiet assenjata l-istess valur. libopenrct2ui CustomListView.cpp 510
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}Il-kodiċi jidher pjuttost stramba. Jidhirli li kien hemm typo jew fil-kundizzjoni jew meta rri-assenja l-varjabbli ColumnHeaderPressedCurrentState valuri falza.
Output
Kif nistgħu naraw, l-integrazzjoni tal-analizzatur statiku PVS-Studio fil-proġett TeamCity tiegħek hija pjuttost sempliċi. Biex tagħmel dan, huwa biżżejjed li tikteb fajl ta 'konfigurazzjoni żgħir wieħed biss. L-iċċekkjar tal-kodiċi jippermettilek tidentifika l-problemi immedjatament wara l-assemblaġġ, li tgħin biex teliminahom meta l-kumplessità u l-ispiża tal-bidliet ikunu għadhom baxxi.
Jekk trid taqsam dan l-artikolu ma 'udjenza li titkellem bl-Ingliż, jekk jogħġbok uża l-link tat-traduzzjoni: Vladislav Stolyarov. .
Sors: www.habr.com
