Saat ini, sistem cloud CI adalah layanan yang sangat diminati. Pada artikel ini, kami akan memberi tahu Anda cara mengintegrasikan analisis kode sumber ke platform cloud CI dengan alat yang sudah tersedia di PVS-Studio. Sebagai contoh, kami akan menggunakan layanan Travis CI.

Mengapa kita mempertimbangkan awan pihak ketiga dan tidak membuat awan kita sendiri? Ada beberapa alasan, yang utama adalah bahwa implementasi SaaS merupakan prosedur yang cukup mahal dan sulit. Sebenarnya, itu adalah tugas yang sederhana dan sepele untuk langsung mengintegrasikan analisis PVS-Studio ke dalam platform cloud pihak ketiga - apakah itu platform terbuka seperti CircleCI, Travis CI, GitLab, atau solusi perusahaan tertentu yang hanya digunakan di perusahaan tertentu. Oleh karena itu kita dapat mengatakan bahwa PVS-Studio sudah tersedia "di awan". Masalah lain adalah implementasi dan memastikan akses ke infrastruktur 24/7. Ini adalah tugas yang lebih rumit. PVS-Studio tidak akan menyediakan platform cloud sendiri secara langsung untuk menjalankan analisisnya.
Beberapa Informasi tentang Perangkat Lunak Bekas
Travis CI adalah layanan untuk membangun dan menguji perangkat lunak yang menggunakan GitHub sebagai penyimpanan. Travis CI tidak memerlukan perubahan kode pemrograman untuk menggunakan layanan ini. Semua pengaturan dibuat dalam file
.travis.yml yang terletak di root repositori.
Kami akan menggunakan
LXC (Linux Containers) sebagai proyek uji coba untuk PVS-Studio. Ini adalah sistem virtualisasi di tingkat sistem operasi untuk meluncurkan beberapa instance OS Linux pada satu node.
Proyek ini kecil, tetapi lebih dari cukup untuk demonstrasi. Output dari perintah cloc:
Catatan: Pengembang LXC sudah menggunakan Travis CI, jadi kami akan mengambil file konfigurasinya sebagai basis dan mengeditnya untuk tujuan kami.
Konfigurasi
Untuk mulai bekerja dengan Travis CI, kami mengikuti
tautan dan masuk menggunakan akun GitHub.
Di jendela yang terbuka, kita harus masuk ke Travis CI.
Setelah otorisasi, pengalihan ke halaman pembuka "Pertama kali di sini? Mari kita mulai! "
, di mana kami menemukan deskripsi singkat apa yang harus dilakukan setelah itu untuk memulai:
- memungkinkan repositori;
- tambahkan file .travis.yml di repositori;
- mulai build pertama.
Mari kita mulai melakukan tindakan ini.
Untuk menambahkan repositori kami di Travis CI, kami pergi ke pengaturan profil dengan
tautan dan tekan "Aktifkan".
Setelah diklik, sebuah jendela akan terbuka untuk memilih repositori tempat aplikasi Travis CI akan diberi akses.
Catatan: untuk memberikan akses ke repositori, akun Anda harus memiliki hak administrator untuk melakukannya.
Setelah itu kami memilih repositori yang tepat, konfirmasikan pilihan dengan tombol "Setuju & Instal", dan kami akan diarahkan kembali ke halaman pengaturan profil.
Mari kita tambahkan beberapa variabel yang akan kita gunakan untuk membuat file lisensi penganalisa dan mengirimkan laporannya. Untuk melakukan ini, kita akan pergi ke halaman pengaturan - tombol "Pengaturan" di sebelah kanan repositori yang diperlukan.
Jendela pengaturan akan terbuka.
Deskripsi singkat tentang pengaturan;
- Bagian "Umum" - mengonfigurasi pemicu tugas mulai otomatis;
- Bagian "Pembatalan Otomatis" memungkinkan untuk mengonfigurasi pembatalan pembuatan otomatis;
- Bagian “Variabel Lingkungan” memungkinkan untuk mendefinisikan variabel lingkungan yang berisi informasi terbuka dan rahasia, seperti informasi login, kunci ssh;
- Bagian "Cron Jobs" adalah konfigurasi dari jadwal menjalankan tugas.
Di bagian "Variabel Lingkungan" kita akan membuat variabel
PVS_USERNAME dan
PVS_KEY yang masing -
masing berisi nama pengguna dan kunci lisensi untuk penganalisa statis. Jika Anda tidak memiliki lisensi PVS-Studio permanen, Anda dapat
meminta lisensi uji coba .
Di sini kami akan membuat variabel
MAIL_USER dan
MAIL_PASSWORD , yang berisi nama pengguna dan kata sandi email, yang akan kami gunakan untuk mengirim laporan.
Saat menjalankan tugas, Travis CI mengambil instruksi dari file .travis.yml, yang terletak di root repositori.
Dengan menggunakan Travis CI, kita dapat menjalankan analisis statis baik secara langsung pada mesin virtual dan menggunakan wadah yang telah dikonfigurasikan untuk melakukannya. Hasil dari pendekatan ini tidak berbeda satu sama lain. Namun, penggunaan wadah yang sudah dikonfigurasi sebelumnya dapat bermanfaat. Misalnya, jika kami sudah memiliki wadah dengan beberapa lingkungan spesifik, di dalamnya produk perangkat lunak mana yang dibangun dan diuji dan kami tidak ingin mengembalikan lingkungan ini di Travis CI.
Mari kita membuat konfigurasi untuk menjalankan analisa pada mesin virtual.
Untuk membuat dan menguji kami akan menggunakan mesin virtual di Ubuntu Trusty, deskripsinya tersedia di
tautan .
Pertama-tama, kami menetapkan bahwa proyek ditulis dalam C dan daftar kompiler yang akan kami gunakan untuk membangun:
language: c compiler: - gcc - clang
Catatan: jika Anda menentukan lebih dari satu kompiler, tugas akan berjalan secara bersamaan untuk masing-masing kompilator. Baca lebih lanjut di
sini .
Sebelum membangun kita perlu menambahkan repositori analyzer, mengatur dependensi dan paket tambahan:
before_install: - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - wget -q -O - https:
Sebelum kami membangun sebuah proyek, kami perlu menyiapkan lingkungan Anda:
script: - ./coccinelle/run-coccinelle.sh -i - git diff --exit-code - export CFLAGS="-Wall -Werror" - export LDFLAGS="-pthread -lpthread" - ./autogen.sh - rm -Rf build - mkdir build - cd build - ../configure --enable-tests --with-distro=unknown
Selanjutnya, kita perlu membuat file lisensi dan mulai menganalisis proyek.
Kemudian kita membuat file lisensi untuk penganalisa dengan perintah pertama. Data untuk
variabel $ PVS_USERNAME dan
$ PVS_KEY diambil dari pengaturan proyek.
- pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic
Dengan perintah selanjutnya, kita mulai melacak pembangunan proyek.
- pvs-studio-analyzer trace -- make -j4
Setelah itu kami menjalankan analisis statis.
Catatan: saat menggunakan lisensi percobaan, Anda perlu menentukan parameter
--disableLicenseExpirationCheck .
- pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic -o PVS-Studio-${CC}.log --disableLicenseExpirationCheck
File dengan hasil analisis dikonversi ke dalam laporan-html dengan perintah terakhir.
- plog-converter -t html PVS-Studio-${CC}.log -o PVS-Studio-${CC}.html
Karena TravisCI tidak mengizinkan Anda mengubah format pemberitahuan email, pada langkah terakhir kami akan menggunakan paket sendemail untuk mengirim laporan:
- sendemail -t mail@domain.com -u "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -m "PVS-Studio $CC report, commit:$TRAVIS_COMMIT" -s smtp.gmail.com:587 -xu $MAIL_USER -xp $MAIL_PASSWORD -o tls=yes -f $MAIL_USER -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html
Berikut ini adalah teks lengkap file konfigurasi untuk menjalankan alat analisa pada mesin virtual:
language: c compiler: - gcc - clang before_install: - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - wget -q -O - https:
Untuk menjalankan PVS-Studio dalam sebuah wadah, mari kita pra-membuatnya menggunakan Dockerfile berikut:
FROM docker.io/ubuntu:trusty ENV CFLAGS="-Wall -Werror" ENV LDFLAGS="-pthread -lpthread" RUN apt-get update && apt-get install -y software-properties-common wget \ && wget -q -O - https:
Dalam hal ini, file konfigurasi mungkin terlihat seperti ini:
before_install: - docker pull docker.io/oandreev/lxc env: - CC=gcc - CC=clang script: - docker run --rm --cap-add SYS_PTRACE -v $(pwd):/pvs -w /pvs docker.io/oandreev/lxc /bin/bash -c " ./coccinelle/run-coccinelle.sh -i && git diff --exit-code && ./autogen.sh && mkdir build && cd build && ../configure CC=$CC && pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY -o PVS-Studio.lic && pvs-studio-analyzer trace -- make -j4 && pvs-studio-analyzer analyze -j2 -l PVS-Studio.lic -o PVS-Studio-$CC.log --disableLicenseExpirationCheck && plog-converter -t html -o PVS-Studio-$CC.html PVS-Studio-$CC.log && sendemail -t mail@domain.com -u 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT' -m 'PVS-Studio $CC report, commit:$TRAVIS_COMMIT' -s smtp.gmail.com:587 -xu $MAIL_USER -xp $MAIL_PASSWORD -o tls=yes -f $MAIL_USER -a PVS-Studio-${CC}.log PVS-Studio-${CC}.html"
Seperti yang Anda lihat, dalam hal ini kami tidak melakukan apa pun di dalam mesin virtual, dan semua tindakan untuk membangun dan menguji proyek berlangsung di dalam wadah.
Catatan : saat Anda memulai wadah, Anda perlu menentukan parameter
--cap-add SYS_PTRACE atau
--security-opt seccomp: unconfined , karena panggilan sistem ptrace digunakan untuk pelacakan kompiler.
Selanjutnya, kita memuat file konfigurasi di root repositori dan melihat bahwa Travis CI telah diberitahu tentang perubahan dalam proyek dan secara otomatis memulai pembangunan.
Detail kemajuan pembuatan dan penganalisa dapat dilihat di konsol.
Setelah tes selesai, kami akan menerima dua email: yang pertama - dengan hasil analisis statis untuk membangun proyek menggunakan gcc, dan yang kedua - untuk dentang masing-masing.
Secara singkat tentang hasil pemeriksaan
Secara umum, proyek ini cukup bersih, analis hanya mengeluarkan 24 peringatan dengan kepastian tinggi dan 46 kepastian sedang. Mari kita lihat beberapa pemberitahuan menarik:
Kondisi redundan di if
V590 Pertimbangkan untuk memeriksa
ekspresi 'ret! = (- 1) && ret == 1'. Ekspresi berlebihan atau mengandung kesalahan cetak. lampirkan.c 107
#define EOF -1 static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) { .... while (getline(&line, &line_bufsz, proc_file) != -1) { ret = sscanf(line, "CapBnd: %llx", &info->capability_mask); if (ret != EOF && ret == 1)
Jika
ret == 1 , jelas tidak sama dengan -1 (EOF). Cek berlebihan,
ret! = EOF dapat dihapus.
Dua peringatan serupa telah dikeluarkan:
- V590 Pertimbangkan untuk memeriksa ekspresi 'ret! = (- 1) && ret == 1'. Ekspresi berlebihan atau mengandung kesalahan cetak. attach.c 579
- V590 Pertimbangkan untuk memeriksa ekspresi 'ret! = (- 1) && ret == 1'. Ekspresi berlebihan atau mengandung kesalahan cetak. attach.c 583
Hilangnya bit tinggi
V784 Ukuran bit mask kurang dari ukuran operan pertama. Ini akan menyebabkan hilangnya bit yang lebih tinggi. conf.c 1879
struct mount_opt { char *name; int clear; int flag; }; static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) { struct mount_opt *mo; for (mo = &mount_opt[0]; mo->name != NULL; mo++) { if (strncmp(opt, mo->name, strlen(mo->name)) == 0) { if (mo->clear) { *flags &= ~mo->flag;
Di Linux,
long adalah variabel integer 64-bit,
flag-> adalah variabel integer 32-bit. Penggunaan
flag> sebagai bit mask akan menyebabkan hilangnya 32 bit tinggi. Topeng bit secara implisit dilemparkan ke variabel integer 64-bit setelah inversi bitwise. Bit tinggi dari topeng ini bisa hilang.
Saya akan menunjukkannya menggunakan contoh:
unsigned long long x; unsigned y; .... x &= ~y;
Ini versi kode yang benar:
*flags &= ~(unsigned long)(mo->flag);
Penganalisa mengeluarkan peringatan serupa lainnya:
- V784 Ukuran bit mask kurang dari ukuran operan pertama. Ini akan menyebabkan hilangnya bit yang lebih tinggi. conf.c 1933
Loop mencurigakan
V612 Suatu 'pengembalian' tanpa syarat dalam satu lingkaran. conf.c 3477
#define lxc_list_for_each(__iterator, __list) \ for (__iterator = (__list)->next; __iterator != __list; \ __iterator = __iterator->next) static bool verify_start_hooks(struct lxc_conf *conf) { char path[PATH_MAX]; struct lxc_list *it; lxc_list_for_each (it, &conf->hooks[LXCHOOK_START]) { int ret; char *hookname = it->elem; ret = snprintf(path, PATH_MAX, "%s%s", conf->rootfs.path ? conf->rootfs.mount : "", hookname); if (ret < 0 || ret >= PATH_MAX) return false; ret = access(path, X_OK); if (ret < 0) { SYSERROR("Start hook \"%s\" not found in container", hookname); return false; } return true; // <= } return true; }
Loop dimulai dan terputus pada iterasi pertama. Ini mungkin dibuat secara sengaja, tetapi dalam kasus ini loop bisa dihilangkan.
Indeks Array di luar Batas
V557 Array underrun dimungkinkan. Nilai indeks 'bytes - 1' dapat mencapai -1. network.c 2570
static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcname, struct lxc_netdev *netdev, pid_t pid, unsigned int hooks_version) { int bytes; char buffer[PATH_MAX] = {0}; .... bytes = lxc_read_nointr(pipefd[0], &buffer, PATH_MAX); if (bytes < 0) { SYSERROR("Failed to read from pipe file descriptor"); close(pipefd[0]); } else { buffer[bytes - 1] = '\0'; } .... }
Bytes dibaca di buffer dari pipa. Jika terjadi kesalahan, fungsi
lxc_read_nointr akan mengembalikan nilai negatif. Jika semua berjalan dengan sukses, terminal nol ditulis oleh elemen terakhir. Namun, jika 0 byte dibaca, indeks akan keluar dari batas buffer, yang mengarah ke perilaku yang tidak ditentukan.
Penganalisa mengeluarkan peringatan serupa lainnya:
- V557 Array underrun dimungkinkan. Nilai indeks 'bytes - 1' dapat mencapai -1. network.c 2725
Buffer overflow
V576 Format salah. Pertimbangkan untuk memeriksa argumen aktual ketiga dari fungsi 'sscanf'. Berbahaya menggunakan penspesifikasi string tanpa spesifikasi lebar. Buffer overflow dimungkinkan. lxc_unshare.c 205
static bool lookup_user(const char *oparg, uid_t *uid) { char name[PATH_MAX]; .... if (sscanf(oparg, "%u", uid) < 1) { if (sscanf(oparg, "%s", name) < 1)
Dalam hal ini, penggunaan
sscanf bisa berbahaya, karena jika buffer
oparq lebih besar dari buffer
nama , indeks akan keluar batas ketika membentuk
nama buffer.
Kesimpulan
Seperti yang kita lihat, ini adalah tugas yang cukup sederhana untuk mengonfigurasi pemeriksaan penganalisa kode statis di cloud. Untuk ini, kita hanya perlu menambahkan satu file dalam repositori dan menghabiskan sedikit waktu menyiapkan sistem CI. Akibatnya, kami akan mendapatkan alat untuk mendeteksi masalah pada tahap penulisan kode. Alat ini memungkinkan kami mencegah bug dari mencapai tahap pengujian berikutnya, di mana perbaikannya akan membutuhkan banyak waktu dan upaya.
Tentu saja, penggunaan PVS-Studio dengan platform cloud tidak hanya terbatas pada Travis CI. Mirip dengan metode yang dijelaskan dalam artikel, dengan perbedaan kecil, analisis PVS-Studio dapat diintegrasikan ke dalam solusi cloud CI populer lainnya, seperti CircleCI, GitLab, dll.
Tautan yang bermanfaat
- Untuk informasi tambahan tentang menjalankan PVS-Studio di Linux dan MacOS, ikuti tautan .
- Anda juga dapat membaca tentang membuat, mengatur dan menggunakan wadah dengan penganalisis kode statis PVS-Studio yang diinstal melalui tautan .
- Dokumentasi TravisCI .