பிவிஎஸ்-ஸ்டுடியோ பகுப்பாய்வியைப் பயன்படுத்துவதற்கான தற்போதைய காட்சிகளில் ஒன்று சிஐ அமைப்புகளுடன் அதன் ஒருங்கிணைப்பு ஆகும். எந்தவொரு தொடர்ச்சியான ஒருங்கிணைப்பு அமைப்பிலிருந்தும் ஒரு PVS-ஸ்டுடியோ திட்டத்தின் பகுப்பாய்வு ஒரு சில கட்டளைகளில் கட்டமைக்கப்படலாம் என்றாலும், இந்த செயல்முறையை இன்னும் வசதியாக நாங்கள் தொடர்கிறோம். PVS-Studio இப்போது பகுப்பாய்வி வெளியீட்டை TeamCity - TeamCity இன்ஸ்பெக்ஷன் வகைக்கான வடிவமைப்பாக மாற்றுவதற்கான ஆதரவைக் கொண்டுள்ளது. அது எப்படி வேலை செய்கிறது என்று பார்க்கலாம்.
பயன்படுத்தப்படும் மென்பொருள் பற்றிய தகவல்கள்
ஆய்வில் உள்ள திட்டம் பற்றிய தகவல்
ஒரு நடைமுறை எடுத்துக்காட்டில் இந்த செயல்பாட்டை முயற்சிப்போம் - OpenRCT2 திட்டத்தை பகுப்பாய்வு செய்வோம்.
சரிசெய்தல்
நேரத்தை மிச்சப்படுத்த, நிறுவல் செயல்முறையைத் தவிர்த்துவிட்டு, எனது கணினியில் TeamCity சர்வர் இயங்கும் தருணத்திலிருந்து தொடங்குவேன். நாம் இதற்குச் செல்ல வேண்டும்: லோக்கல் ஹோஸ்ட்:{நிறுவலின் போது குறிப்பிடப்பட்ட போர்ட்} (என் விஷயத்தில், லோக்கல் ஹோஸ்ட்:9090) மற்றும் அங்கீகாரத் தரவை உள்ளிடவும். உள்ளே நுழைந்த பிறகு எங்களை வரவேற்கும்:
உருவாக்கு திட்டத்தை கிளிக் செய்யவும். அடுத்து, கைமுறையாகத் தேர்ந்தெடுத்து புலங்களை நிரப்பவும்.
பொத்தானை அழுத்திய பின் உருவாக்கு, அமைப்புகளுடன் கூடிய சாளரம் நம்மை வரவேற்கிறது.
கிளிக் செய்யலாம் கட்டமைப்பை உருவாக்கவும்.
புலங்களை நிரப்பி கிளிக் செய்யவும் உருவாக்கு. பதிப்புக் கட்டுப்பாட்டு அமைப்பைத் தேர்ந்தெடுக்கும்படி கேட்கும் சாளரத்தைக் காண்கிறோம். ஆதாரங்கள் ஏற்கனவே உள்ளூரில் இருப்பதால், கிளிக் செய்யவும் செல்க.
இறுதியாக, நாங்கள் திட்ட அமைப்புகளுக்கு செல்கிறோம்.
சட்டசபை படிகளைச் சேர்ப்போம், இதைச் செய்ய, கிளிக் செய்யவும்: கட்ட படிகள் -> கட்டமைக்கும் படியைச் சேர்க்கவும்.
இங்கே நாம் தேர்வு செய்கிறோம்:
- ரன்னர் வகை -> கட்டளை வரி
- இயக்கவும் -> தனிப்பயன் ஸ்கிரிப்ட்
திட்டத் தொகுப்பின் போது நாங்கள் பகுப்பாய்வு செய்வோம் என்பதால், அசெம்பிளி மற்றும் பகுப்பாய்வு ஒரு படியாக இருக்க வேண்டும், எனவே புலத்தை நிரப்பவும் தனிப்பயன் ஸ்கிரிப்ட்:
தனித்தனியான படிகளை பின்னர் பார்ப்போம். பகுப்பாய்வியை ஏற்றுவது, திட்டத்தை அசெம்பிள் செய்வது, பகுப்பாய்வு செய்வது, அறிக்கையை வெளியிடுவது மற்றும் வடிவமைத்தல் ஆகியவை பதினொரு கோடு குறியீடுகளை மட்டுமே எடுக்கும்.
நாம் செய்ய வேண்டிய கடைசி விஷயம், சுற்றுச்சூழல் மாறிகளை அமைப்பது, அவற்றின் வாசிப்புத்திறனை மேம்படுத்த சில வழிகளை நான் கோடிட்டுக் காட்டியுள்ளேன். இதைச் செய்ய, தொடரலாம்: அளவுருக்கள் -> புதிய அளவுருவைச் சேர்க்கவும் மற்றும் மூன்று மாறிகளைச் சேர்க்கவும்:
பொத்தானை அழுத்தினால் போதும் ரன் மேல் வலது மூலையில். திட்டம் ஒருங்கிணைக்கப்பட்டு பகுப்பாய்வு செய்யப்படும்போது, ஸ்கிரிப்டைப் பற்றி நான் உங்களுக்குச் சொல்கிறேன்.
நேரடியாக ஸ்கிரிப்ட்
முதலில், சமீபத்திய பிவிஎஸ்-ஸ்டுடியோ விநியோகத்தைப் பதிவிறக்க வேண்டும். இதற்கு சாக்லேட் பேக்கேஜ் மேனேஜரைப் பயன்படுத்துகிறோம். இதைப் பற்றி மேலும் அறிய விரும்புவோருக்கு, அதற்குரியது உள்ளது
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 வரையிலான வரம்பில் உள்ளது. இரண்டாம் பகுதி: (பட திசை / 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-Studio நிலையான பகுப்பாய்வியை ஒருங்கிணைப்பது மிகவும் எளிது. இதைச் செய்ய, ஒரு சிறிய உள்ளமைவு கோப்பை எழுதினால் போதும். குறியீட்டைச் சரிபார்ப்பது, சட்டசபைக்குப் பிறகு உடனடியாக சிக்கல்களைக் கண்டறிய உங்களை அனுமதிக்கும், இது மாற்றங்களின் சிக்கலான தன்மை மற்றும் செலவு இன்னும் குறைவாக இருக்கும்போது அவற்றை அகற்ற உதவும்.
இந்தக் கட்டுரையை ஆங்கிலம் பேசும் பார்வையாளர்களுடன் பகிர்ந்து கொள்ள விரும்பினால், மொழிபெயர்ப்பு இணைப்பைப் பயன்படுத்தவும்: Vladislav Stolyarov.
ஆதாரம்: www.habr.com