Dies ist eine kurze Geschichte darüber, wie mit PVS-Studio ein Fehler im Quellcode der in PVS-Studio verwendeten Bibliothek gefunden werden konnte. Darüber hinaus nicht theoretisch, sondern tatsächlich - der Fehler wurde in der Praxis bei Verwendung der Bibliothek im Analysegerät manifestiert.
In PVS-Studio_Cmd (sowie einigen anderen Dienstprogrammen) verwenden wir eine spezielle Bibliothek zum Parsen von Befehlszeilenargumenten - CommandLine.
Heute war ich damit beschäftigt, den neuen Modus in PVS-Studio_Cmd zu unterstützen, und es kam einfach so vor, dass ich diese Bibliothek von Parsing-Argumenten verwenden musste. Beim Schreiben von Code debugge ich auch, da ich mit unbekannten APIs arbeiten muss.
Also, der Code wird geschrieben, kompiliert, zur Ausführung ausgeführt, ii ...
Die Codeausführung wird an die Bibliothek übergeben, in der eine Ausnahme vom Typ
NullReferenceException auftritt . Von der Seite ist es nicht sehr klar - ich übergebe keine expliziten Nullverweise auf die Methode.
Für alle Fälle schaue ich mir die Kommentare zur aufgerufenen Methode an. Es ist sehr unwahrscheinlich, dass sie die Bedingungen für eine Ausnahme vom Typ
NullReferenceException beschreiben (da Ausnahmen dieses Typs normalerweise, wie mir scheint, unvorhergesehen sind).
In den Kommentaren zur Methode gibt es keine Informationen zu einer
NullReferenceException (was jedoch erwartet wird).
Um zu sehen, was genau die Ausnahme verursacht (und wo), habe ich beschlossen, den Projektquellcode herunterzuladen, die Debug-Version der Bibliothek zu kompilieren und mit dem Analysator zu verbinden. Der Quellcode für das Projekt
ist auf GitHub verfügbar . Version 1.9.71 ist erforderlich, da genau dieser Typ jetzt im Analysator verwendet wird.
Ich lade die entsprechende Version des Quellcodes, sammle, verbinde die Debug-Bibliothek mit dem Analysator, führe den Code zur Ausführung aus und sehe:
Der Ort der Ausnahme ist also klar -
helpInfo ist
null , was beim Zugriff auf die
Left- Instanzeigenschaft eine Ausnahme vom Typ
NullReferenceException verursacht.
Und dann wurde ich nachdenklich. In letzter Zeit wurde PVS-Studio für C # in verschiedenen Bereichen gut verbessert, einschließlich im Bereich der Suche nach Dereferenzierung von potenziell Null-Referenzen. Insbesondere wurde die interprozedurale Analyse verbessert. Daher wurde es für mich sofort interessant, den Quellcode zu überprüfen, um festzustellen, ob PVS-Studio den zur Diskussion stehenden Fehler finden konnte.
Ich überprüfte den Quellcode und sah unter anderem genau das, was ich mir erhofft hatte.
PVS-Studio Warnung :
V3080 Mögliche Null-Dereferenzierung innerhalb der Methode unter 'helpInfo.Left'. Überprüfen Sie das zweite Argument: helpInfo. Parser.cs 405
Ja, da ist es! Genau das, was Sie brauchen. Schauen wir uns den Quellcode genauer an.
private bool DoParseArgumentsVerbs( string[] args, object options, ref object verbInstance) { var verbs = ReflectionHelper.RetrievePropertyList<VerbOptionAttribute>(options); var helpInfo = ReflectionHelper.RetrieveMethod<HelpVerbOptionAttribute>(options); if (args.Length == 0) { if (helpInfo != null || _settings.HelpWriter != null) { DisplayHelpVerbText(options, helpInfo, null);
Der Analysator generiert beim Aufrufen der
DisplayHelpVerbText- Methode eine Warnmeldung und warnt vor dem zweiten Argument -
helpInfo . Beachten Sie, dass sich diese Methode im
then- Zweig der
if-Anweisung befindet . Der bedingte Ausdruck ist so zusammengesetzt, dass die Verzweigung mit den folgenden Werten von Variablen ausgeführt werden kann:
- helpInfo == null ;
- _settings.HelpWriter! = null ;
Sehen wir uns den Hauptteil der
DisplayHelpVerbText- Methode an:
private void DisplayHelpVerbText( object options, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, string verb) { string helpText; if (verb == null) { HelpVerbOptionAttribute.InvokeMethod(options, helpInfo, null, out helpText); } else { HelpVerbOptionAttribute.InvokeMethod(options, helpInfo, verb, out helpText); } if (_settings.HelpWriter != null) { _settings.HelpWriter.Write(helpText); } }
Da
verb == null (siehe Methodenaufruf) interessiert uns der
then- Zweig der
if-Anweisung . Obwohl die Situation mit dem
else- Zweig ähnlich sein wird, werden wir den
then- Zweig betrachten, da in unserem speziellen Fall die Ausführung durch ihn erfolgte. Denken
Sie daran, dass
helpInfo null sein kann .
Schauen wir uns nun den Hauptteil der
HelpVerbOptionAttribute.InvokeMethod- Methode an. Eigentlich haben Sie es bereits im obigen Screenshot gesehen:
internal static void InvokeMethod( object target, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, string verb, out string text) { text = null; var method = helpInfo.Left; if (!CheckMethodSignature(method)) { throw new MemberAccessException( SR.MemberAccessException_BadSignatureForHelpVerbOptionAttribute .FormatInvariant(method.Name)); } text = (string)method.Invoke(target, new object[] { verb }); }
helpInfo.Left wird bedingungslos aufgerufen, obwohl
helpInfo null sein kann . Der Analysator warnte davor und dies geschah.
FazitEs stellte sich als witzig heraus, dass mit Hilfe von PVS-Studio ein Fehler im Code der in PVS-Studio verwendeten Bibliothek gefunden werden konnte. Ich denke, dies ist eine Art Fortsetzung der Antwort auf die Frage „Findet PVS-Studio Fehler im PVS-Studio-Code?“. :) Es kann Fehler nicht nur im PVS-Studio-Code finden, sondern auch im Code der verwendeten Bibliotheken.
Schließlich schlage ich vor,
den Analysator herunterzuladen und zu versuchen, Ihr Projekt zu überprüfen - was ist, wenn Sie dort auch etwas Interessantes finden können?

Wenn Sie diesen Artikel einem englischsprachigen Publikum zugänglich machen möchten, verwenden Sie bitte den Link zur Übersetzung: Sergey Vasiliev.
Die Geschichte, wie PVS-Studio einen Fehler in der in ... PVS-Studio verwendeten Bibliothek gefunden hat