PVS Studio.VS Analisis statistik GCC 10. Mini-test independen

Setelah kemunculan artikel terjemahan tentang Analisis Statis di GCC 10 , dan reaksi yang diharapkan dari perwakilan pengembang penganalisa statis komersial PVS-Studio yang ada di sini, saya bertanya: โ€œMengapa para perwakilan menolak untuk menguji produk mereka dengan contoh sederhana untuk analisis statis, dan tidak menyembunyikan mereka Apakah mereka? "
Andrey2008Ya, itu tidak menarik bagi saya. Tertangkap / tidak menangkap kesalahan sintetis, ini tidak mengatakan apa-apa tentang kemampuan penganalisa
Haruskah mereka entah bagaimana menjalankan unit test produk mereka dan bagaimana, jika tidak dengan contoh sederhana sintetis seperti itu ?!

Sebenarnya, saya harus melakukannya sendiri.

Tes nomor 1. Contoh paling sederhana dari kesalahan bebas ganda


Didiagnosis dengan:
V586 Fungsi 'bebas' dipanggil dua kali untuk deallokasi ruang memori yang sama. Periksa argumen pertama. Periksa baris: 5, 6. 1_dbl_free.c 6

Lulus

Nomor tes 2. longjmp () dengan gratis ()


Bersumpah yang tidak dapat dipahami pada konstanta di malloc, tetapi kesalahan terdeteksi - kode tidak dapat diakses dan memori yang tidak digunakan:
V118 malloc () berfungsi menerima ekspresi berbahaya dalam kapasitas argumen. 2_longjump.c 13
V779 Kode yang tidak dapat dideteksi terdeteksi. Mungkin saja ada kesalahan. 2_longjump.c 15
V799 Variabel 'ptr' tidak digunakan setelah memori dialokasikan untuk itu. Pertimbangkan untuk memeriksa penggunaan variabel ini. 2_longjump.c 13

Lulus

Tes nomor 3. Malloc () kebocoran dan fopen () file tidak tertutup


Ditemukan:
V118 malloc () berfungsi menerima ekspresi berbahaya dalam kapasitas argumen. 3_fopen.c 7
V773 Cakupan visibilitas dari pegangan file 'f' keluar tanpa menutup file. Kebocoran sumber daya mungkin terjadi. 3_fopen.c 9
V773 Cakupan visibilitas dari pointer 'p' keluar tanpa melepaskan memori. Kebocoran memori dimungkinkan. 3_fopen.c 9
V799 Variabel 'p' tidak digunakan setelah memori dialokasikan untuk itu. Pertimbangkan untuk memeriksa penggunaan variabel ini. 3_fopen.c 7

Lulus

Nomor tes 4. Memantau penggunaan memori setelah membebaskannya


Bug Detected:
V774 Pointer 'n' digunakan setelah memori dilepaskan. 4_use_after_free.c 9
V591 Fungsi non-void harus mengembalikan nilai. 4_use_after_free.c 11

Lulus

Nomor tes 5. Kontrol pelepasan pointer non-heap (heap)


Peringatan non-error dikeluarkan:
V104 Konversi implisit 'n' ke tipe memsize dalam ekspresi aritmatika: sizeof (int) * n 5_free_nonheap.c 11
V799 Variabel 'ptr' tidak digunakan setelah memori dialokasikan untuknya. Pertimbangkan untuk memeriksa penggunaan variabel ini. 5_free_nonheap.c 11

Gagal

Nomor tes 6. Handler sinyal dalam panggilan () salah


Gagal

Meskipun ini adalah diagnosis yang spesifik sehingga saya tidak akan mencelanya.

Selanjutnya, saya memeriksa daftar diagnostik di GCC 10 dan menambahkan contoh, jadi tes lebih lanjut dengan kode sumber.

Tes nomor 7. Dobel menutup file dan melepaskan FILE tertutup *


PVS tidak mendeteksi kesalahan ini
GCC 10 mendeteksi double-fclose tetapi tidak mendeteksi bebas untuk pegangan yang tertutup.

#include <stdlib.h>
void closefile(FILE* f) {
	fclose(f);
}

void test(const char *filename) {
  FILE *f = fopen(filename, "r");
  void *p = malloc(1024);
  /* do stuff */
  closefile(f);
  fclose(f);
  free (p);
  free(f);  // <-  UB
}

Gagal

Nomor tes 8. longjmp () pada tumpukan usang


PVS tidak melihat apa pun, GCC10 bekerja dengan benar

#include <setjmp.h>
#include <stdlib.h>
static jmp_buf env;
static int i;

static void inner(void) {
  longjmp(env, 1);
}

static void middle(void) {
  inner();
}

void outer(void) {
  i = setjmp(env);
}

void outer_x2(void) {
  outer();
  if (i == 0)
    middle();
}

Gagal

Nomor tes 9. Kembalikan pointer ke tumpukan variabel


Gagal oleh kedua peserta, meskipun dalam kasus sederhana, GCC mendeteksi ini, tetapi ini bukan fungsi -fanalyzer (atau mungkin belum diimplementasikan).

#include<stdlib.h>

struct str1 {
    char buf[10];
};

struct str1 * ret(int sel)
{
    struct str1  var1, *pval;

    if(sel == 1)
        pval = &var1;
    else if(sel != 1)
        pval = (struct str1 *)malloc(1000);

    return pval;
}

Gagal

Tes nomor 10. Diagnosis array-nilai-indeks dan penggunaan-nilai-tidak-diinisialisasi


Sepertinya mereka belum bekerja di fanalyzer GCC10 .

PVS menangkap ini, seperti yang telah ditunjukkan berkali-kali.

Lulus

Kesimpulan


Pasti ada analisis statis di PVS-Studio.

Meskipun bukan tanpa beberapa kelemahan, ada baiknya menggunakannya, terutama karena banyak kesalahan manusia akan terdeteksi, tidak hanya dari bidang analisis statis.

All Articles