Strukturierte SARIF-Diagnose
Der MSVC-Compiler kann zur Ausgabediagnose als SARIF (Static Analysis Results Interchange Format) erfolgen. SARIF ist ein maschinenlesbares JSON-basiertes Format.
Es gibt zwei Möglichkeiten, den MSVC-Compiler zur Erstellung von SARIF-Diagnosen zu machen:
- Übergeben Sie den
/experimental:log
Schalter an die Befehlszeile. Ausführliche Informationen finden Sie in der Dokumentation/experimental:log
. - Starten Sie programmgesteuert, und legen Sie
cl.exe
dieSARIF_OUTPUT_PIPE
Umgebungsvariable fest, um SARIF-Blöcke über eine Pipe abzurufen.
Abrufen von SARIF über ein Rohr
Tools, die SARIF vom MSVC-Compiler verbrauchen, während eine Kompilierung in Bearbeitung ist, verwenden eine Pipe. Ausführliche Informationen zum Erstellen von Windows-Rohren finden Sie in der Dokumentation CreatePipe
.
Um SARIF über eine Pipe abzurufen, legen Sie die Umgebungsvariable SARIF_OUTPUT_PIPE
auf die UTF-16-codierte ganzzahlige Darstellung des HANDLE
Schreibendes der Pipe fest, und starten Sie cl.exe
dann . SARIF wird wie folgt entlang des Rohrs gesendet:
- Wenn eine neue Diagnose verfügbar ist, wird sie in diese Pipe geschrieben.
- Die Diagnose wird nicht als gesamtes SARIF-Objekt, sondern einzeln in die Rohrleitung geschrieben.
- Jede Diagnose wird durch eine JSON-RPC 2.0-Nachricht vom Typ Benachrichtigung dargestellt.
- Der JSON-RPC-Nachricht wird eine
Content-Length
Kopfzeile mit dem FormularContent-Length: <N>
vorangestellt, gefolgt von zwei Newlines, wobei<N>
die Länge der folgenden JSON-RPC-Nachricht in Byte angegeben ist. - Die JSON-RPC-Nachricht und der Header werden in UTF-8 codiert.
- Dieses JSON-RPC-with-header-Format ist mit vs-streamjsonrpc kompatibel.
- Der Methodenname für den JSON-RPC-Aufruf lautet
OnSarifResult
. - Der Aufruf verfügt über einen einzelnen Parameter, der anhand des Namens des Parameters
result
codiert wird. - Der Wert des Arguments ist ein einzelnes
result
Objekt, das durch den SARIF Version 2.1-Standard angegeben wird.
Beispiel
Hier ist ein Beispiel für ein JSON-RPC SARIF-Ergebnis, das von 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}}}]}}}
SARIF-Ergebnisdaten
Der Compiler gibt SARIF aus, die zusätzliche Informationen enthalten können, um die geschachtelte Struktur einiger Diagnosen darzustellen. Eine Diagnose (dargestellt durch ein result
SARIF-Objekt) kann eine "Diagnosestruktur" mit zusätzlichen Informationen in seinem relatedLocations
Feld enthalten. Diese Struktur wird mit einem SARIF-Eigenschaftenbehälter wie folgt codiert:
Das Feld eines location
Objekts properties
kann eine nestingLevel
Eigenschaft enthalten, deren Wert die Tiefe dieser Position in der Diagnosestruktur ist. Wenn ein Speicherort nicht über einen nestingLevel
angegebenen Wert verfügt, wird als Tiefe betrachtet 0
, und dieser Speicherort ist ein untergeordnetes Element der Stammdiagnose, die durch das Objekt dargestellt wird, das result
es enthält. Andernfalls ist der Wert größer als die Tiefe der Position, die relatedLocations
unmittelbar vor dieser Position im Feld liegt, ein untergeordnetes Element dieser Position. Andernfalls ist diese Position ein gleichgeordnetes Element des am nächsten vorangehenden location
relatedLocations
Felds mit derselben Tiefe.
Beispiel
Betrachten Sie folgenden Code:
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
Wenn dieser Code kompiliert wird, erzeugt der Compiler das folgende result
Objekt (physicalLocation
Eigenschaften wurden aus Platzgründen entfernt):
{
"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)'"
}
}
]
}
Die logische Diagnosestruktur, die aus den Nachrichten in diesem result
Objekt erzeugt wird, lautet:
- "Pet": Keine überladene Funktion konnte alle Argumenttypen konvertieren.
- könnte "void pet(cat)" sein
- "void pet(cat)": Argument 1 kann nicht von "Lizard" in "Katze" konvertiert werden.
- Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung ausführen kann, oder der Operator kann nicht aufgerufen werden.
- "void pet(cat)": Argument 1 kann nicht von "Lizard" in "Katze" konvertiert werden.
- oder "void pet(dog)"
- "void pet(dog)": Argument 1 kann nicht von "Lizard" in "Hund" umgewandelt werden.
- Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung ausführen kann, oder der Operator kann nicht aufgerufen werden.
- "void pet(dog)": Argument 1 kann nicht von "Lizard" in "Hund" umgewandelt werden.
- beim Versuch, der Argumentliste "(Lizard)" zuzuordnen
- könnte "void pet(cat)" sein
Siehe auch
/experimental:log
(Aktivieren der strukturierten SARIF-Diagnose)