PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Salah sawijining skenario paling anyar kanggo nggunakake analisa PVS-Studio yaiku integrasi karo sistem CI. Lan sanajan analisa proyek PVS-Studio saka meh kabeh sistem integrasi terus-terusan bisa dibangun mung sawetara printah, kita terus nggawe proses iki luwih trep. PVS-Studio saiki duwe dhukungan kanggo ngowahi output analisa dadi format kanggo TeamCity - TeamCity Inspections Type. Ayo ndeleng cara kerjane.

Informasi babagan piranti lunak sing digunakake

PVS Studio - analyzer statis saka C, C ++, C # lan kode Jawa, dirancang kanggo nggampangake tugas nemokake lan mbenerake macem-macem jinis kasalahan. Analisa bisa digunakake ing Windows, Linux lan macOS. Ing artikel iki kita bakal aktif nggunakake ora mung analyzer dhewe, nanging uga sawetara keperluan saka distribusi sawijining.

CLMonitor - minangka server ngawasi sing ngawasi peluncuran kompiler. Iki kudu langsung ditindakake sadurunge miwiti mbangun proyek sampeyan. Ing mode snooping, server bakal nyegat kabeh kompiler sing didhukung. Wigati dicathet yen sarana iki mung bisa digunakake kanggo nganalisa proyek C / C ++.

PlogConverter - sarana kanggo ngowahi laporan analisa menyang macem-macem format.

Informasi babagan proyek sing diteliti

Coba fungsi iki kanthi conto praktis - ayo nganalisa proyek OpenRCT2.

OpenRCT2 - implementasine mbukak saka game RollerCoaster Tycoon 2 (RCT2), ngembangaken karo fungsi anyar lan ndandani kewan omo. Gameplay muter babagan mbangun lan njaga taman hiburan sing ngemot wahana, toko, lan fasilitas. Pamuter kudu nyoba kanggo nggawe MediaWiki lan njaga reputasi apik taman nalika tetep tamu seneng. OpenRCT2 ngidini sampeyan muter ing skenario lan kothak wedhi. Skenario mbutuhake pemain kanggo ngrampungake tugas tartamtu ing wektu sing ditemtokake, nalika Sandbox ngidini pemain mbangun taman sing luwih fleksibel tanpa watesan utawa finansial.

imbuhan

Kanggo ngirit wektu, aku mbokmenawa bakal ngliwati proses instalasi lan miwiti saka wayahe nalika server TeamCity mlaku ing komputer. Kita kudu pindhah menyang: localhost: {port sing ditemtokake sajrone proses instalasi} (ing kasusku, localhost: 9090) lan ketik data wewenang. Sawise mlebu kita bakal disambut dening:

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Klik tombol Nggawe Proyek. Sabanjure, pilih Manual lan isi kolom.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Sawise mencet tombol nggawe, kita disambut dening jendhela karo setelan.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Ayo klik Nggawe konfigurasi mbangun.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Isi kolom lan klik nggawe. Kita ndeleng jendhela sing njaluk sampeyan milih sistem kontrol versi. Wiwit sumber wis ana ing lokal, klik Skip.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Pungkasan, kita pindhah menyang setelan proyek.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Ayo nambah langkah-langkah perakitan, kanggo nindakake iki klik: Mbangun langkah -> Tambah langkah mbangun.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Kene kita milih:

  • Tipe Runner -> Command Line
  • Run -> Custom Script

Awit kita bakal nindakake analisis sajrone kompilasi proyek, perakitan lan analisis kudu dadi siji langkah, mula isi lapangan Skrip Khusus:

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Kita bakal nliti langkah-langkah individu mengko. Penting loading analyzer, ngumpulake proyek, nganalisa, output laporan lan format mung mbutuhake sewelas baris kode.

Babagan pungkasan sing kudu ditindakake yaiku nyetel variabel lingkungan, sing aku wis mbatesi sawetara cara kanggo nambah keterbacaan. Kanggo nindakake iki, ayo nerusake: Parameter -> Tambah parameter anyar lan nambah telung variabel:

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Sampeyan mung kudu mencet tombol Run ing pojok tengen ndhuwur. Nalika proyek kasebut dirakit lan dianalisis, aku bakal ngandhani babagan naskah kasebut.

Langsung skrip

Pisanan, kita kudu ngundhuh distribusi PVS-Studio paling anyar. Kanggo iki, kita nggunakake manajer paket Chocolatey. Kanggo sing pengin ngerti luwih lengkap babagan iki, ana sing cocog artikel:

choco install pvs-studio -y

Sabanjure, ayo miwiti utilitas pelacakan proyek CLMonitor.

%CLmon% monitor –-attach

Banjur kita bakal mbangun proyek kasebut minangka variabel lingkungan MSB iku path kanggo versi MSBuild aku kudu mbangun

%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable

Ayo ketik login lan kunci lisensi kanggo PVS-Studio:

%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%

Sawise mbangun rampung, bukak CLmonitor maneh kanggo ngasilake file sing wis diproses lan analisis statis:

%CLmon% analyze -l "c:ptest.plog"

Banjur kita bakal nggunakake sarana liyane saka distribusi kita. PlogConverter ngowahi laporan saka format standar menyang format khusus TeamCity. Thanks kanggo iki, kita bakal bisa ndeleng langsung ing jendhela mbangun.

%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"

Langkah pungkasan yaiku nampilake laporan format ing stdout, ngendi iku bakal dijupuk dening TeamCity parser.

type "C:tempptest.plog_TeamCity.txt"

Kode skrip lengkap:

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"

Ing sawetoro wektu, perakitan lan analisis proyek wis rampung kanthi sukses, kita bisa pindhah menyang tab projects lan priksa manawa.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Saiki ayo klik Inspeksi Totalkanggo pindhah menyang ndeleng laporan analyzer:

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Bebaya diklompokakΓ© miturut nomer aturan diagnostik. Kanggo navigasi liwat kode, sampeyan kudu ngeklik ing nomer baris karo bebaya. Ngeklik tandha pitakon ing pojok sisih ndhuwur bakal mbukak tab anyar kanthi dokumentasi. Sampeyan uga bisa navigasi liwat kode kanthi ngeklik ing nomer baris karo bebaya analyzer. Navigasi saka komputer remot bisa nalika nggunakake SourceTreeRoot panandha. Sapa wae sing kasengsem ing mode operasi penganalisa iki bisa kenal karo bagean sing cocog dokumentasi.

Ndeleng asil analyzer

Saiki kita wis rampung deploying lan configuring mbangun, ayo kang njupuk dipikir ing sawetara bebaya menarik ditemokakΓ© ing project kita lagi looking ing.

Warning N1

V773 [CWE-401] Pangecualian kasebut dibuwang tanpa ngeculake pointer 'asil'. A bocor memori bisa. 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;
}

Analisa weruh kesalahan sing sawise mbosenke allocating memori ing CreateObject, nalika ana pangecualian, memori ora dibusak, lan ana bocor memori.

Warning N2

V501 Ana sub-ekspresi sing padha '(1ULL << WIDX_MONTH_BOX)' ing sisih kiwa lan ing sisih tengen '|' operator. 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),
  ....
};

Sawetara wong saliyane analisa statis bisa lulus tes perhatian iki. Conto copy-paste iki apik kanggo alesan iki.

Warning N3

V703 Aneh yen kolom 'gendera' ing kelas asale 'RCT12BannerElement' nimpa lapangan ing kelas dasar 'RCT12TileElementBase'. Priksa garis: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570

struct RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};
struct rct1_peep : RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};

Mesthi, nggunakake variabel kanthi jeneng sing padha ing kelas dhasar lan ing turunan ora tansah kesalahan. Nanging, teknologi warisan dhewe nganggep yen kabeh lapangan kelas induk ana ing kelas anak. Kanthi nyatakake lapangan kanthi jeneng sing padha ing ahli waris, kita ngenalake kebingungan.

Warning N4

V793 Aneh yen asil pernyataan 'imageDirection / 8' minangka bagean saka kondisi kasebut. Mbok, statement iki kudu dibandhingake karo liyane. libopenrct2 ObservationTower.cpp 38

void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
  if ((imageDirection / 8) && (imageDirection / 8) != 3)
  {
    ....
  }
  ....
}

Ayo dideleng kanthi cetha. Ekspresi gambarArah/8 bakal palsu yen gambarArah ana ing kisaran saka -7 nganti 7. Bagian kapindho: (gambarArah / 8) != 3 mriksa gambarArah kanggo njaba sawetara: saka -31 kanggo -24 lan saka 24 kanggo 31, mungguh. Iku misale jek cukup aneh kanggo kula mriksa nomer kanggo Gawan ing sawetara tartamtu ing cara iki lan, sanajan ora ana kesalahan ing Piece saka kode, Aku nyaranake rewriting kahanan iki dadi luwih eksplisit. Iki bakal nggawe urip luwih gampang kanggo wong sing maca lan njaga kode iki.

Warning N5

V587 Urutan tugas sing aneh kaya iki: A = B; B = A;. Priksa baris: 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;
      ....
  }
  ....
}

Fragmen kode iki paling mungkin dipikolehi kanthi dekompilasi. Banjur, miturut komentar sing ditinggalake, bagean saka kode sing ora bisa digunakake wis dibusak. Nanging, isih ana sawetara operasi sing isih ana kursorId, kang uga ora nggawe akeh pangertèn.

Warning N6

V1004 [CWE-476] Pointer 'pamuter' digunakake ora aman sawise diverifikasi marang nullptr. Priksa baris: 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);                    // <=
  }
  ....
}

Kode iki gampang dibenerake; sampeyan mung kudu mriksa kaping telune pamuter menyang null pointer, utawa nambah menyang awak statement kondisional. Aku bakal menehi saran pilihan kapindho:

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);
    }
  }
  ....
}

Warning N7

V547 [CWE-570] Ekspresi 'jeneng == nullptr' tansah palsu. 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));
    ....
  }
  ....
}

Sampeyan bisa ngilangi baris kode sing angel diwaca kanthi cepet lan ngrampungake masalah kanthi mriksa nullptr. Aku saranake ngganti kode kaya ing ngisor iki:

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);
    ....
  }
  ....
}

Warning N8

V1048 [CWE-1164] Variabel 'ColumnHeaderPressedCurrentState' diwenehi nilai sing padha. libopenrct2ui CustomListView.cpp 510

void CustomListView::MouseUp(....)
{
  ....
  if (!ColumnHeaderPressedCurrentState)
  {
    ColumnHeaderPressed = std::nullopt;
    ColumnHeaderPressedCurrentState = false;
    Invalidate();
  }
}

Kode katon cukup aneh. Iku misale jek kula sing ana salah ketik salah siji ing kondisi utawa nalika maneh nemtokake variabel ColumnHeaderPressedCurrentState angka palsu.

kesimpulan

Kaya sing kita deleng, nggabungake analisa statis PVS-Studio menyang proyek TeamCity sampeyan cukup gampang. Kanggo nindakake iki, cukup nulis mung siji file konfigurasi cilik. Priksa kode bakal ngidini sampeyan ngenali masalah sanalika sawise perakitan, sing bakal mbantu ngilangi nalika kerumitan lan biaya owah-owahan isih sithik.

PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2
Yen sampeyan pengin nuduhake artikel iki karo pamirsa sing nganggo basa Inggris, gunakake tautan terjemahan: Vladislav Stolyarov. PVS-Studio lan Integrasi Terus: TeamCity. Analisis proyek Open RollerCoaster Tycoon 2.

Source: www.habr.com

Add a comment