Een van die mees huidige scenario's vir die gebruik van die PVS-Studio-ontleder is die integrasie daarvan met CI-stelsels. En alhoewel die ontleding van 'n PVS-Studio-projek vanaf byna enige deurlopende integrasiestelsel in net 'n paar opdragte ingebou kan word, gaan ons voort om hierdie proses nog geriefliker te maak. PVS-Studio het nou ondersteuning vir die omskakeling van ontleder-uitset in 'n formaat vir TeamCity - TeamCity Inspections Type. Kom ons kyk hoe dit werk.
Inligting oor die sagteware wat gebruik word
Inligting oor die projek wat bestudeer word
Kom ons probeer hierdie funksionaliteit op 'n praktiese voorbeeld - kom ons ontleed die OpenRCT2-projek.
aanpassing
Om tyd te bespaar, sal ek waarskynlik die installasieproses oorslaan en begin vanaf die oomblik dat ek die TeamCity-bediener op my rekenaar het. Ons moet gaan na: localhost:{poort gespesifiseer tydens die installasieproses} (in my geval, localhost:9090) en magtigingsdata invoer. Nadat ons ingegaan het sal ons begroet word deur:
Klik op die Skep projek-knoppie. Kies dan Handmatig en vul die velde in.
Nadat u die knoppie gedruk het Skep, word ons begroet deur 'n venster met instellings.
Kom ons klik Skep bou-konfigurasie.
Vul die velde in en klik Skep. Ons sien 'n venster wat jou vra om 'n weergawebeheerstelsel te kies. Aangesien die bronne reeds plaaslik geleë is, klik Slaan oor.
Ten slotte gaan ons aan na die projekinstellings.
Kom ons voeg monteerstappe by, om dit te doen, klik: Boustappe -> Voeg boustap by.
Hier kies ons:
- Runner tipe -> Command Line
- Hardloop -> Pasgemaakte skrip
Aangesien ons analise tydens projeksamestelling sal uitvoer, moet samestelling en ontleding een stap wees, so vul die veld in Aangepaste skrif:
Ons sal later na individuele stappe kyk. Dit is belangrik dat die laai van die ontleder, die samestelling van die projek, die ontleding daarvan, die uitvoer van die verslag en die formatering daarvan slegs elf reëls kode neem.
Die laaste ding wat ons moet doen is om die omgewingsveranderlikes in te stel, wat ek 'n paar maniere uiteengesit het om hul leesbaarheid te verbeter. Om dit te doen, kom ons gaan aan: Parameters -> Voeg nuwe parameter by en voeg drie veranderlikes by:
Al wat jy hoef te doen is om die knoppie te druk Run in die regter boonste hoek. Terwyl die projek saamgestel en ontleed word, sal ek jou van die draaiboek vertel.
Skryf direk
Eerstens moet ons die nuutste PVS-Studio-verspreiding aflaai. Hiervoor gebruik ons die Chocolatey-pakketbestuurder. Vir diegene wat meer hieroor wil weet, is daar 'n ooreenstemmende
choco install pvs-studio -y
Kom ons begin dan die CLMonitor-projekbou-opsporingshulpmiddel.
%CLmon% monitor –-attach
Dan sal ons die projek as 'n omgewingsveranderlike bou MSB is die pad na die weergawe van MSBuild wat ek moet bou
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
Kom ons voer die aanmeld- en lisensiesleutel vir PVS-Studio in:
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
Nadat die bou voltooi is, voer CLMonitor weer uit om voorafverwerkte lêers en statiese analise te genereer:
%CLmon% analyze -l "c:ptest.plog"
Dan sal ons 'n ander hulpprogram uit ons verspreiding gebruik. PlogConverter skakel 'n verslag van 'n standaardformaat na 'n TeamCity-spesifieke formaat om. Danksy dit sal ons dit direk in die bouvenster kan sien.
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
Die laaste stap is om die geformateerde verslag in te vertoon standout, waar dit deur die TeamCity-ontleder opgetel sal word.
type "C:tempptest.plog_TeamCity.txt"
Volledige skrif kode:
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"
Intussen is die samestelling en ontleding van die projek suksesvol afgehandel, ons kan na die blad gaan projekte en maak seker daarvan.
Kom ons klik nou op Inspeksies Totaalom na die ontlederverslag te gaan kyk:
Waarskuwings word volgens diagnostiese reëlnommers gegroepeer. Om deur die kode te navigeer, moet jy op die reëlnommer met die waarskuwing klik. As u op die vraagteken in die regter boonste hoek klik, sal u 'n nuwe oortjie met dokumentasie oopmaak. Jy kan ook deur die kode navigeer deur op die reëlnommer met die ontlederwaarskuwing te klik. Navigasie vanaf 'n afgeleë rekenaar is moontlik wanneer dit gebruik word SourceTreeRoot merker. Enigiemand wat belangstel in hierdie werkswyse van die ontleder kan hulself vergewis van die ooreenstemmende afdeling
Kyk na die ontleder se resultate
Noudat ons klaar is met die implementering en konfigurasie van die bou, kom ons kyk na 'n paar interessante waarskuwings wat gevind word in die projek waarna ons kyk.
Waarskuwing 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;
}
Die ontleder het 'n fout opgemerk wat na die dinamiese toewysing van geheue in Skep Voorwerp, wanneer 'n uitsondering voorkom, word die geheue nie uitgevee nie, en 'n geheuelek vind plaas.
Waarskuwing 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),
....
};
Min mense anders as 'n statiese ontleder kan hierdie aandagstoets slaag. Hierdie copy-paste-voorbeeld is juis om hierdie rede goed.
Waarskuwings N3
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
Die gebruik van 'n veranderlike met dieselfde naam in die basisklas en in die afstammeling is natuurlik nie altyd 'n fout nie. Oorerwingstegnologie self aanvaar egter dat al die velde van die ouerklas in die kinderklas teenwoordig is. Deur velde met dieselfde naam in die erfgenaam te verklaar, lei ons verwarring.
Waarskuwing N4
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}
Kom ons kyk van naderby. Uitdrukking beeldrigting/8 sal vals wees as beeldrigting is in die reeks van -7 tot 7. Tweede deel: (imageDirection / 8) != 3 tjeks beeldrigting omdat dit buite die reeks is: onderskeidelik van -31 tot -24 en van 24 tot 31. Dit lyk vir my nogal vreemd om nommers vir insluiting in 'n sekere reeks op hierdie manier na te gaan en, selfs al is daar geen fout in hierdie stukkie kode nie, sal ek aanbeveel om hierdie voorwaardes te herskryf om meer eksplisiet te wees. Dit sou die lewe baie makliker maak vir die mense wat hierdie kode sou lees en onderhou.
Waarskuwing 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;
....
}
....
}
Hierdie kodefragment is heel waarskynlik deur dekompilasie verkry. Toe, te oordeel aan die kommentaar wat gelaat is, is 'n deel van die nie-werkende kode verwyder. Daar is egter nog 'n paar operasies oor cursorId, wat ook nie veel sin maak nie.
Waarskuwing 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); // <=
}
....
}
Hierdie kode is redelik maklik om reg te stel; jy hoef dit net 'n derde keer na te gaan speler by 'n nulwyser, of voeg dit by die liggaam van die voorwaardelike stelling. Ek sou die tweede opsie voorstel:
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);
}
}
....
}
Waarskuwing 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));
....
}
....
}
Jy kan in een klap ontslae raak van 'n moeilik leesbare reël kode en die probleem oplos deur te kyk vir nullptr. Ek stel voor dat u die kode soos volg verander:
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);
....
}
....
}
Waarskuwing N8
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}
Die kode lyk nogal vreemd. Dit lyk vir my of daar 'n tikfout was óf in die toestand óf wanneer die veranderlike hertoegewys is ColumnHeaderPressedCurrentState wat beteken valse.
Output
Soos ons kan sien, is die integrasie van die PVS-Studio statiese ontleder in jou TeamCity-projek redelik eenvoudig. Om dit te doen, is dit genoeg om net een klein konfigurasielêer te skryf. Deur die kode na te gaan, sal u probleme onmiddellik na montering kan identifiseer, wat sal help om dit uit te skakel wanneer die kompleksiteit en koste van veranderinge nog laag is.
As jy hierdie artikel met 'n Engelssprekende gehoor wil deel, gebruik asseblief die vertaalskakel: Vladislav Stolyarov.
Bron: will.com