Bagikan melalui


Diagnostik SARIF Terstruktur

Pengkompilasi MSVC dapat dibuat untuk menghasilkan diagnostik sebagai SARIF (Format Pertukaran Hasil Analisis Statis). SARIF adalah format berbasis JSON yang dapat dibaca mesin.

Ada dua cara untuk membuat kompilator MSVC menghasilkan diagnostik SARIF:

  • Teruskan /experimental:log sakelar pada baris perintah. Lihat dokumentasi untuk /experimental:log detailnya.
  • Luncurkan cl.exe secara terprogram dan atur SARIF_OUTPUT_PIPE variabel lingkungan untuk mengambil blok SARIF melalui pipa.

Mengambil SARIF melalui pipa

Alat yang menggunakan SARIF dari pengkompilasi MSVC saat kompilasi sedang berlangsung menggunakan pipa. Lihat dokumentasi untuk CreatePipe detail tentang membuat pipa Windows.

Untuk mengambil SARIF melalui pipa, atur SARIF_OUTPUT_PIPE variabel lingkungan menjadi representasi bilangan bulat yang dikodekan UTF-16 dari HANDLE ke ujung tulis pipa, lalu luncurkan cl.exe. SARIF dikirim di sepanjang pipa sebagai berikut:

  • Ketika diagnostik baru tersedia, diagnostik ditulis ke pipa ini.
  • Diagnostik ditulis ke pipa satu per satu daripada sebagai seluruh objek SARIF.
  • Setiap diagnostik diwakili oleh pesan JSON-RPC 2.0 jenis Pemberitahuan.
  • Pesan JSON-RPC diawali dengan Content-Length header dengan formulir Content-Length: <N> diikuti oleh dua baris baru, di mana <N> panjang pesan JSON-RPC berikut dalam byte.
  • Pesan dan header JSON-RPC keduanya dikodekan dalam UTF-8.
  • Format JSON-RPC-with-header ini kompatibel dengan vs-streamjsonrpc.
  • Nama metode untuk panggilan JSON-RPC adalah OnSarifResult.
  • Panggilan memiliki parameter tunggal yang dikodekan berdasarkan nama dengan nama resultparameter .
  • Nilai argumen adalah objek tunggal result seperti yang ditentukan oleh standar SARIF Versi 2.1.

Contoh

Berikut adalah contoh hasil JSON-RPC SARIF yang dihasilkan oleh cl.exe:

Content-Length: 334

{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}

Data hasil SARIF

Kompilator menghasilkan SARIF yang mungkin menyertakan informasi tambahan untuk mewakili struktur berlapis dari beberapa diagnostik. Diagnostik (diwakili oleh result objek SARIF) mungkin berisi "pohon diagnostik" informasi tambahan di bidangnya relatedLocations . Pohon ini dikodekan menggunakan tas properti SARIF sebagai berikut:

Bidang location objek properties mungkin berisi nestingLevel properti yang nilainya adalah kedalaman lokasi ini di pohon diagnostik. Jika lokasi tidak memiliki nestingLevel yang ditentukan, kedalaman dianggap 0 dan lokasi ini adalah anak dari diagnostik akar yang diwakili oleh result objek yang berisinya. Jika tidak, jika nilai lebih besar dari kedalaman lokasi segera sebelum lokasi ini di relatedLocations bidang , lokasi ini adalah anak dari lokasi tersebut. Jika tidak, lokasi ini adalah saudara kandung dari yang paling dekat sebelumnya location di relatedLocations bidang dengan kedalaman yang sama.

Contoh

Pertimbangkan gambar berikut:

struct dog {};
struct cat {};

void pet(dog);
void pet(cat);

struct lizard {};

int main() {
    pet(lizard{});
}

Ketika kode ini dikompilasi, pengkompilasi menghasilkan objek berikut result (physicalLocation properti telah dihapus untuk brevity):

{
    "ruleId": "C2665",
    "level": "error",
    "message": {
        "text": "'pet': no overloaded function could convert all the argument types"
    },
    "relatedLocations": [
        {
            "id": 0,
            "message": {
                "text": "could be 'void pet(cat)'"
            }
        },
        {
            "id": 1,
            "message": {
                "text": "'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat'"
            },
            "properties": {
                "nestingLevel": 1
            }
        },
        {
            "id": 2,
            "message": {
                "text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
            },
            "properties": {
                "nestingLevel": 2
            }
        },
        {
            "id": 3,
            "message": {
                "text": "or       'void pet(dog)'"
            }
        },
        {
            "id": 4,
            "message": {
                "text": "'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'"
            },
            "properties": {
                "nestingLevel": 1
            }
        },
        {
            "id": 5,
            "message": {
                "text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
            },
            "properties": {
                "nestingLevel": 2
            }
        },
        {
            "id": 6,
            "message": {
                "text": "while trying to match the argument list '(lizard)'"
            }
        }
    ]
}

Pohon diagnostik logis yang dihasilkan dari pesan dalam objek ini result adalah:

  • 'pet': tidak ada fungsi kelebihan beban yang dapat mengonversi semua jenis argumen
    • bisa jadi 'void pet(cat)'
      • 'void pet(cat)': tidak dapat mengonversi argumen 1 dari 'kadal' ke 'kucing
        • Tidak tersedia operator konversi yang ditentukan pengguna yang dapat melakukan konversi ini, atau operator tidak dapat dipanggil
    • atau 'void pet(dog)'
      • 'void pet(dog)': tidak dapat mengonversi argumen 1 dari 'kadal' menjadi 'anjing'
        • Tidak tersedia operator konversi yang ditentukan pengguna yang dapat melakukan konversi ini, atau operator tidak dapat dipanggil
    • saat mencoba mencocokkan daftar argumen '(kadal)'

Baca juga

/experimental:log (Aktifkan diagnostik SARIF terstruktur)