PVS-స్టూడియో ఎనలైజర్ని ఉపయోగించడం కోసం అత్యంత ప్రస్తుత దృశ్యాలలో ఒకటి CI సిస్టమ్లతో దాని ఏకీకరణ. మరియు దాదాపు ఏదైనా నిరంతర ఏకీకరణ వ్యవస్థ నుండి PVS-స్టూడియో ప్రాజెక్ట్ యొక్క విశ్లేషణ కేవలం కొన్ని ఆదేశాలలో నిర్మించబడినప్పటికీ, మేము ఈ ప్రక్రియను మరింత సౌకర్యవంతంగా చేయడానికి కొనసాగిస్తాము. PVS-Studio ఇప్పుడు TeamCity - TeamCity తనిఖీల రకం కోసం ఎనలైజర్ అవుట్పుట్ను ఫార్మాట్లోకి మార్చడానికి మద్దతునిస్తోంది. ఇది ఎలా పని చేస్తుందో చూద్దాం.
ఉపయోగించిన సాఫ్ట్వేర్ గురించి సమాచారం
అధ్యయనంలో ఉన్న ప్రాజెక్ట్ గురించి సమాచారం
ఆచరణాత్మక ఉదాహరణలో ఈ కార్యాచరణను ప్రయత్నిద్దాం - OpenRCT2 ప్రాజెక్ట్ను విశ్లేషిద్దాం.
సర్దుబాటు
సమయాన్ని ఆదా చేయడానికి, నేను బహుశా ఇన్స్టాలేషన్ ప్రాసెస్ను దాటవేసి, నా కంప్యూటర్లో TeamCity సర్వర్ రన్ అవుతున్న క్షణం నుండి ప్రారంభిస్తాను. మనం దీనికి వెళ్లాలి: localhost:{ఇన్స్టాలేషన్ ప్రాసెస్లో పేర్కొన్న పోర్ట్} (నా విషయంలో, localhost:9090) మరియు అధికార డేటాను నమోదు చేయండి. ప్రవేశించిన తర్వాత మాకు స్వాగతం పలుకుతారు:
సృష్టించు ప్రాజెక్ట్ బటన్పై క్లిక్ చేయండి. తరువాత, మాన్యువల్గా ఎంచుకోండి మరియు ఫీల్డ్లను పూరించండి.
బటన్ నొక్కిన తర్వాత సృష్టించు, మేము సెట్టింగ్లతో కూడిన విండో ద్వారా స్వాగతం పలికాము.
క్లిక్ చేద్దాం బిల్డ్ కాన్ఫిగరేషన్ను సృష్టించండి.
ఫీల్డ్లను పూరించండి మరియు క్లిక్ చేయండి సృష్టించు. సంస్కరణ నియంత్రణ వ్యవస్థను ఎంచుకోమని మిమ్మల్ని అడుగుతున్న విండోను మేము చూస్తాము. మూలాధారాలు ఇప్పటికే స్థానికంగా ఉన్నందున, క్లిక్ చేయండి దాటవేయి.
చివరగా, మేము ప్రాజెక్ట్ సెట్టింగులకు వెళ్తాము.
అసెంబ్లీ దశలను జోడిద్దాం, దీన్ని చేయడానికి: బిల్డ్ స్టెప్స్ -> బిల్డ్ స్టెప్ జోడించండి.
ఇక్కడ మేము ఎంచుకుంటాము:
- రన్నర్ రకం -> కమాండ్ లైన్
- రన్ -> కస్టమ్ స్క్రిప్ట్
ప్రాజెక్ట్ కంపైలేషన్ సమయంలో మేము విశ్లేషణ చేస్తాము కాబట్టి, అసెంబ్లీ మరియు విశ్లేషణ ఒక దశగా ఉండాలి, కాబట్టి ఫీల్డ్ను పూరించండి అనుకూల స్క్రిప్ట్:
మేము తరువాత వ్యక్తిగత దశలను పరిశీలిస్తాము. ఎనలైజర్ను లోడ్ చేయడం, ప్రాజెక్ట్ను అసెంబ్లింగ్ చేయడం, దానిని విశ్లేషించడం, నివేదికను అవుట్పుట్ చేయడం మరియు ఫార్మాటింగ్ చేయడం వంటి వాటికి పదకొండు లైన్ల కోడ్ మాత్రమే అవసరం.
పర్యావరణం వేరియబుల్స్ని సెట్ చేయడం మనం చేయవలసిన చివరి విషయం, వాటి రీడబిలిటీని మెరుగుపరచడానికి నేను కొన్ని మార్గాలను వివరించాను. దీన్ని చేయడానికి, ముందుకు వెళ్దాం: పారామితులు -> కొత్త పరామితిని జోడించండి మరియు మూడు వేరియబుల్స్ జోడించండి:
మీరు చేయాల్సిందల్లా బటన్ను నొక్కడమే రన్ ఎగువ కుడి మూలలో. ప్రాజెక్ట్ అసెంబుల్ చేయబడి, విశ్లేషించబడుతున్నప్పుడు, నేను మీకు స్క్రిప్ట్ గురించి చెబుతాను.
నేరుగా స్క్రిప్ట్
ముందుగా, మేము తాజా PVS-స్టూడియో పంపిణీని డౌన్లోడ్ చేసుకోవాలి. దీని కోసం మేము చాక్లెట్ ప్యాకేజీ మేనేజర్ని ఉపయోగిస్తాము. దీని గురించి మరింత తెలుసుకోవాలనుకునే వారికి, సంబంధితంగా ఉంది
choco install pvs-studio -y
తర్వాత, CLMonitor ప్రాజెక్ట్ బిల్డ్ ట్రాకింగ్ యుటిలిటీని ప్రారంభిద్దాం.
%CLmon% monitor –-attach
అప్పుడు మేము ప్రాజెక్ట్ను పర్యావరణ వేరియబుల్గా నిర్మిస్తాము ఎంఎస్బి నేను నిర్మించాల్సిన MSBuild సంస్కరణకు మార్గం
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
PVS-స్టూడియో కోసం లాగిన్ మరియు లైసెన్స్ కీని నమోదు చేద్దాం:
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
బిల్డ్ పూర్తయిన తర్వాత, ముందుగా ప్రాసెస్ చేయబడిన ఫైల్లు మరియు స్టాటిక్ విశ్లేషణను రూపొందించడానికి CLMonitorని మళ్లీ అమలు చేయండి:
%CLmon% analyze -l "c:ptest.plog"
అప్పుడు మేము మా పంపిణీ నుండి మరొక ప్రయోజనాన్ని ఉపయోగిస్తాము. PlogConverter ఒక నివేదికను ప్రామాణిక ఫార్మాట్ నుండి TeamCity-నిర్దిష్ట ఆకృతికి మారుస్తుంది. దీనికి ధన్యవాదాలు, మేము బిల్డ్ విండోలో నేరుగా వీక్షించగలుగుతాము.
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
ఆకృతీకరించిన నివేదికను ప్రదర్శించడం చివరి దశ stdout, ఎక్కడ అది TeamCity పార్సర్ ద్వారా తీసుకోబడుతుంది.
type "C:tempptest.plog_TeamCity.txt"
పూర్తి స్క్రిప్ట్ కోడ్:
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"
ఈలోగా, ప్రాజెక్ట్ యొక్క అసెంబ్లీ మరియు విశ్లేషణ విజయవంతంగా పూర్తయింది, మేము ట్యాబ్కు వెళ్లవచ్చు ప్రాజెక్ట్స్ и убедиться в эtom.
ఇప్పుడు క్లిక్ చేద్దాం తనిఖీలు మొత్తంఎనలైజర్ నివేదికను వీక్షించడానికి:
హెచ్చరికలు విశ్లేషణ నియమ సంఖ్యల ద్వారా సమూహం చేయబడ్డాయి. కోడ్ ద్వారా నావిగేట్ చేయడానికి, మీరు హెచ్చరికతో కూడిన లైన్ నంబర్పై క్లిక్ చేయాలి. ఎగువ కుడి మూలలో ఉన్న ప్రశ్న గుర్తుపై క్లిక్ చేయడం ద్వారా మీకు డాక్యుమెంటేషన్తో కూడిన కొత్త ట్యాబ్ తెరవబడుతుంది. మీరు ఎనలైజర్ హెచ్చరికతో లైన్ నంబర్పై క్లిక్ చేయడం ద్వారా కూడా కోడ్ ద్వారా నావిగేట్ చేయవచ్చు. ఉపయోగించినప్పుడు రిమోట్ కంప్యూటర్ నుండి నావిగేషన్ సాధ్యమవుతుంది SourceTreeRoot మార్కర్. ఎనలైజర్ యొక్క ఈ ఆపరేషన్ మోడ్లో ఆసక్తి ఉన్న ఎవరైనా సంబంధిత విభాగంతో తమను తాము పరిచయం చేసుకోవచ్చు
ఎనలైజర్ ఫలితాలను వీక్షించడం
ఇప్పుడు మేము బిల్డ్ని అమలు చేయడం మరియు కాన్ఫిగర్ చేయడం పూర్తి చేసాము, మనం చూస్తున్న ప్రాజెక్ట్లో కనిపించే కొన్ని ఆసక్తికరమైన హెచ్చరికలను చూద్దాం.
హెచ్చరిక 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;
}
డైనమిక్గా మెమరీని కేటాయించిన తర్వాత ఎనలైజర్ లోపాన్ని గమనించారు క్రియేట్ ఆబ్జెక్ట్, మినహాయింపు సంభవించినప్పుడు, మెమరీ క్లియర్ చేయబడదు మరియు మెమరీ లీక్ ఏర్పడుతుంది.
హెచ్చరిక 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),
....
};
స్టాటిక్ ఎనలైజర్ కాకుండా కొంతమంది వ్యక్తులు ఈ శ్రద్ధ పరీక్షలో ఉత్తీర్ణత సాధించగలరు. ఈ కాపీ-పేస్ట్ ఉదాహరణ ఖచ్చితంగా ఈ కారణంగా మంచిది.
హెచ్చరికలు N3
struct RCT12SpriteBase
{
....
uint8_t flags;
....
};
struct rct1_peep : RCT12SpriteBase
{
....
uint8_t flags;
....
};
వాస్తవానికి, బేస్ క్లాస్లో మరియు డిసెండెంట్లో ఒకే పేరుతో వేరియబుల్ని ఉపయోగించడం ఎల్లప్పుడూ లోపం కాదు. అయితే, వారసత్వ సాంకేతికత స్వయంగా పిల్లల తరగతిలో మాతృ తరగతికి చెందిన అన్ని రంగాలు ఉన్నట్లు ఊహిస్తుంది. వారసుడిలో అదే పేరుతో ఫీల్డ్లను ప్రకటించడం ద్వారా, మేము గందరగోళాన్ని పరిచయం చేస్తాము.
హెచ్చరిక N4
void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
if ((imageDirection / 8) && (imageDirection / 8) != 3)
{
....
}
....
}
నిశితంగా పరిశీలిద్దాం. వ్యక్తీకరణ ఇమేజ్ డైరెక్షన్/8 ఉంటే అబద్ధం అవుతుంది చిత్రం దిశ -7 నుండి 7 వరకు ఉంటుంది. రెండవ భాగం: (imageDirection / 8) != 3 తనిఖీలు చిత్రం దిశ పరిధి వెలుపల ఉన్నందుకు: వరుసగా -31 నుండి -24 మరియు 24 నుండి 31 వరకు. ఈ విధంగా ఒక నిర్దిష్ట పరిధిలో చేర్చడం కోసం సంఖ్యలను తనిఖీ చేయడం నాకు చాలా వింతగా అనిపిస్తుంది మరియు ఈ కోడ్ ముక్కలో ఎటువంటి లోపం లేకపోయినా, ఈ షరతులను మరింత స్పష్టంగా ఉండేలా తిరిగి వ్రాయమని నేను సిఫార్సు చేస్తాను. ఇది ఈ కోడ్ని చదివే మరియు నిర్వహించే వ్యక్తులకు జీవితాన్ని చాలా సులభతరం చేస్తుంది.
హెచ్చరిక 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;
....
}
....
}
ఈ కోడ్ ఫ్రాగ్మెంట్ చాలా మటుకు డీకంపైలేషన్ ద్వారా పొందబడింది. ఆపై, వదిలివేయబడిన వ్యాఖ్య ద్వారా నిర్ణయించడం, పని చేయని కోడ్లో కొంత భాగం తీసివేయబడింది. అయితే, ఇంకా కొన్ని ఆపరేషన్లు మిగిలి ఉన్నాయి కర్సర్ఐడ్, ఇది కూడా చాలా అర్ధవంతం కాదు.
హెచ్చరిక 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); // <=
}
....
}
ఈ కోడ్ సరిదిద్దడం చాలా సులభం; మీరు దీన్ని మూడవసారి తనిఖీ చేయాలి క్రీడాకారుడు శూన్య పాయింటర్కి, లేదా షరతులతో కూడిన స్టేట్మెంట్ బాడీకి దాన్ని జోడించండి. నేను రెండవ ఎంపికను సూచిస్తాను:
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);
}
}
....
}
హెచ్చరిక 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));
....
}
....
}
మీరు చదవడానికి కష్టంగా ఉండే కోడ్ లైన్ను ఒక్కసారిగా వదిలించుకోవచ్చు మరియు తనిఖీ చేయడం ద్వారా సమస్యను పరిష్కరించవచ్చు nullptr. కోడ్ను ఈ క్రింది విధంగా మార్చమని నేను సూచిస్తున్నాను:
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);
....
}
....
}
హెచ్చరిక N8
void CustomListView::MouseUp(....)
{
....
if (!ColumnHeaderPressedCurrentState)
{
ColumnHeaderPressed = std::nullopt;
ColumnHeaderPressedCurrentState = false;
Invalidate();
}
}
కోడ్ చాలా వింతగా కనిపిస్తుంది. కండిషన్లో లేదా వేరియబుల్ని మళ్లీ కేటాయించేటప్పుడు అక్షర దోషం ఉన్నట్లు నాకు అనిపిస్తోంది కాలమ్హెడర్ప్రెస్డ్ కరెంట్ స్టేట్ అర్థం తప్పుడు.
తీర్మానం
మేము చూడగలిగినట్లుగా, మీ TeamCity ప్రాజెక్ట్లో PVS-స్టూడియో స్టాటిక్ ఎనలైజర్ని ఏకీకృతం చేయడం చాలా సులభం. దీన్ని చేయడానికి, కేవలం ఒక చిన్న కాన్ఫిగరేషన్ ఫైల్ను వ్రాస్తే సరిపోతుంది. కోడ్ను తనిఖీ చేయడం వలన అసెంబ్లీ తర్వాత వెంటనే సమస్యలను గుర్తించడానికి మిమ్మల్ని అనుమతిస్తుంది, ఇది మార్పుల సంక్లిష్టత మరియు ఖర్చు ఇంకా తక్కువగా ఉన్నప్పుడు వాటిని తొలగించడంలో సహాయపడుతుంది.
మీరు ఈ కథనాన్ని ఇంగ్లీష్ మాట్లాడే ప్రేక్షకులతో భాగస్వామ్యం చేయాలనుకుంటే, దయచేసి అనువాద లింక్ని ఉపయోగించండి: వ్లాడిస్లావ్ స్టోలియారోవ్.
మూలం: www.habr.com