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 aturSARIF_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 formulirContent-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
result
parameter . - 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
- 'void pet(cat)': tidak dapat mengonversi argumen 1 dari 'kadal' ke 'kucing
- 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
- 'void pet(dog)': tidak dapat mengonversi argumen 1 dari 'kadal' menjadi 'anjing'
- saat mencoba mencocokkan daftar argumen '(kadal)'
- bisa jadi 'void pet(cat)'
Baca juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk