Ein af nýjustu atburðarásunum fyrir notkun PVS-Studio greiningartækisins er samþætting þess við CI kerfi. Og þó að greining á PVS-Studio verkefni frá nánast hvaða samfelldu samþættingarkerfi sé hægt að byggja inn í örfáar skipanir, höldum við áfram að gera þetta ferli enn þægilegra. PVS-Studio hefur nú stuðning við að umbreyta úttak greiningartækis í snið fyrir TeamCity - TeamCity Inspections Type. Við skulum sjá hvernig það virkar.
Upplýsingar um hugbúnaðinn sem notaður er
Upplýsingar um verkefnið í rannsókn
Við skulum prófa þessa virkni á hagnýtu dæmi - við skulum greina OpenRCT2 verkefnið.
aðlögun
Til að spara tíma mun ég líklega sleppa uppsetningarferlinu og byrja frá því augnabliki þegar ég er með TeamCity þjóninn í gangi á tölvunni minni. Við þurfum að fara á: localhost:{port tilgreint í uppsetningarferlinu} (í mínu tilfelli, localhost:9090) og slá inn heimildargögn. Eftir inngöngu taka á móti okkur:
Smelltu á hnappinn Búa til verkefni. Næst skaltu velja Handvirkt og fylla út reitina.
Eftir að hafa ýtt á hnappinn Búa til, tekur á móti okkur gluggi með stillingum.
Við skulum smella Búðu til byggingarstillingar.
Fylltu út reitina og smelltu Búa til. Við sjáum glugga sem biður þig um að velja útgáfustýringarkerfi. Þar sem heimildirnar eru þegar staðsettar á staðnum, smelltu Fara.
Að lokum förum við yfir í verkefnastillingarnar.
Við skulum bæta við samsetningarskrefum, til að gera þetta smelltu: Byggingarskref -> Bæta við byggingarskrefum.
Hér veljum við:
- Tegund hlaupara -> Skipanalína
- Keyra -> Sérsniðið forskrift
Þar sem við munum framkvæma greiningu við samantekt verks ætti samsetning og greining að vera eitt skref, svo fylltu út reitinn Sérsniðið handrit:
Við munum skoða einstök skref síðar. Það er mikilvægt að hlaða greiningartækið, setja saman verkefnið, greina það, gefa út skýrsluna og forsníða hana tekur aðeins ellefu línur af kóða.
Það síðasta sem við þurfum að gera er að stilla umhverfisbreyturnar, sem ég hef lýst nokkrum leiðum til að bæta læsileika þeirra. Til að gera þetta skulum við halda áfram: Færibreytur -> Bæta við nýrri færibreytu og bæta við þremur breytum:
Allt sem þú þarft að gera er að ýta á hnappinn Hlaupa í efra hægra horninu. Á meðan verið er að setja saman og greina verkefnið mun ég segja þér frá handritinu.
Beint handrit
Fyrst þurfum við að hlaða niður nýjustu PVS-Studio dreifingunni. Til þess notum við Chocolatey pakkastjórann. Fyrir þá sem vilja vita meira um þetta er samsvarandi
choco install pvs-studio -y
Næst skulum við ræsa CLMonitor verkefnisbyggingarbúnaðinn.
%CLmon% monitor –-attach
Síðan munum við byggja verkefnið upp sem umhverfisbreytu MSB er slóðin að útgáfunni af MSBuild sem ég þarf að smíða
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
Sláum inn innskráningar- og leyfislykilinn fyrir PVS-Studio:
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
Eftir að smíði er lokið skaltu keyra CLMonitor aftur til að búa til forunnar skrár og kyrrstöðugreiningu:
%CLmon% analyze -l "c:ptest.plog"
Þá munum við nota annað tól úr dreifingu okkar. PlogConverter breytir skýrslu úr stöðluðu sniði í TeamCity-sérstakt snið. Þökk sé þessu munum við geta skoðað það beint í byggingarglugganum.
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
Síðasta skrefið er að birta sniðið skýrsluna í stdout, þar sem það verður tekið upp af TeamCity þáttaranum.
type "C:tempptest.plog_TeamCity.txt"
Fullur handritskóð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"
Í millitíðinni hefur samsetningu og greiningu á verkefninu verið lokið með góðum árangri, við getum farið í flipann verkefni og vertu viss um það.
Nú skulum við smella á Skoðanir Samtalstil að fara í að skoða greiningarskýrsluna:
Viðvaranir eru flokkaðar eftir greiningarreglunúmerum. Til að fletta í gegnum kóðann þarftu að smella á línunúmerið með viðvöruninni. Með því að smella á spurningarmerkið í efra hægra horninu opnast nýr flipi með skjölum. Þú getur líka farið í gegnum kóðann með því að smella á línunúmerið með greiningarviðvöruninni. Leiðsögn frá fjartengdri tölvu er möguleg þegar hún er notuð SourceTreeRoot merki. Allir sem hafa áhuga á þessari notkunaraðferð greiningartækisins geta kynnt sér samsvarandi kafla
Skoða niðurstöður greiningartækisins
Nú þegar við erum búin að dreifa og stilla bygginguna skulum við kíkja á nokkrar áhugaverðar viðvaranir sem finnast í verkefninu sem við erum að skoða.
Viðvörun N1
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;
}
Greiningartækið tók eftir villu sem eftir að hafa úthlutað minni á virkan hátt CreateObject, þegar undantekning á sér stað er minnið ekki hreinsað og minnisleki á sér stað.
Viðvörun N2
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),
....
};
Fáir aðrir en kyrrstöðugreiningartæki gætu staðist þetta athyglispróf. Þetta copy-paste dæmi er gott einmitt af þessari ástæðu.
Viðvaranir N3
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
Auðvitað er það ekki alltaf villa að nota breytu með sama nafni í grunnflokknum og í afkvæminu. Hins vegar gerir erfðatæknin sjálf ráð fyrir því að öll svið foreldrabekksins séu til staðar í barnabekknum. Með því að lýsa yfir reitum með sama nafni í erfingjanum kynnum við rugling.
Viðvörun N4
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}
Við skulum skoða nánar. Tjáning imageDirection/8 verður rangt ef imageDirection er á bilinu -7 til 7. Seinni hluti: (imageDirection / 8) != 3 ávísanir imageDirection fyrir að vera utan bilsins: frá -31 til -24 og frá 24 til 31, í sömu röð. Það finnst mér frekar skrítið að athuga tölur fyrir innlimun á ákveðnu bili á þennan hátt og jafnvel þó að það sé engin villa í þessum kóða, þá myndi ég mæla með því að endurskrifa þessi skilyrði til að vera skýrari. Þetta myndi gera lífið miklu auðveldara fyrir fólkið sem myndi lesa og viðhalda þessum kóða.
Viðvörun N5
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;
....
}
....
}
Þetta kóðabrot var líklegast fengið með afsamsetningu. Síðan, miðað við athugasemdina sem skilin var eftir, var hluti af kóðanum sem ekki virkaði fjarlægður. Enn eru þó nokkrar aðgerðir eftir cursorId, sem líka meikar ekki mikið sens.
Viðvörun N6
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); // <=
}
....
}
Það er frekar auðvelt að leiðrétta þennan kóða; þú þarft bara að athuga hann í þriðja sinn leikmaður við núllbendingu, eða bættu því við meginmál skilyrtu yfirlýsingarinnar. Ég myndi mæla með seinni valkostinum:
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);
}
}
....
}
Viðvörun N7
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));
....
}
....
}
Þú getur losað þig við erfiða kóðalínu í einni svipan og leyst vandamálið með því að athuga nullptr. Ég legg til að breyta kóðanum sem hér segir:
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);
....
}
....
}
Viðvörun N8
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}
Kóðinn lítur frekar undarlega út. Mér sýnist að það hafi verið innsláttarvilla annaðhvort í ástandinu eða þegar breytan var endurúthlutað ColumnHeaderPressedCurrentState merkingar rangar.
Output
Eins og við sjáum er það frekar einfalt að samþætta PVS-Studio kyrrstöðugreiningartækið í TeamCity verkefnið þitt. Til að gera þetta er nóg að skrifa eina litla stillingarskrá. Að athuga kóðann gerir þér kleift að bera kennsl á vandamál strax eftir samsetningu, sem mun hjálpa til við að útrýma þeim þegar flókið og kostnaður við breytingar er enn lítill.
Ef þú vilt deila þessari grein með enskumælandi áhorfendum, vinsamlegast notaðu þýðingartengilinn: Vladislav Stolyarov.
Heimild: www.habr.com