Müssen wir noch statische Analysen durchführen? [closed]

Lesezeit: 9 Minuten

Mein Chef ist der Meinung, dass jeder Code, den wir schreiben (in C/C++), den Standards entsprechen muss, die von einem statischen Analysetool (wie MISRA/Lint) vorgegeben werden. Meine Meinung dazu ist, da Compiler heute gut entwickelt sind, ist dies wirklich erforderlich?

Die Frage hier ist, wie effektiv ist diese statische Analyse heutzutage?

  • Compiler erkennen eine andere Art von Fehlern.

    – Dies

    15. April 2014 um 10:27 Uhr


  • Der erste Schritt besteht darin, mit der höchsten Warnstufe zu kompilieren und die Warnung zu entfernen: Sie können alle nicht verwendeten Variablen entfernen, umwandeln, die einen potenziellen Datenverlust verursachen, und anderes. Dies erfordert kein neues Werkzeug und entfernt das offensichtlichste

    – Gabriel

    15. April 2014 um 10:31 Uhr

  • Ich halte es nicht für sinnvoll, sich strikt an diese Standards zu halten. Während MISRA viele gute Regeln hat, sind einige der Regeln zurückgeblieben und erfordern unnötigen Boilerplate-Code, um herumzukommen.

    – Benutzer694733

    15. April 2014 um 10:45 Uhr

  • Ihre erste Frage ist etwas bizarr. Es ist: „Mein Chef hat mir gesagt, ich muss X tun. Ich glaube nicht, dass ich X tun muss. Muss ich X tun?“ Wenn die Richtlinien Ihrer Organisation unklar sind, hilft es wahrscheinlich nicht, Fremde im Internet zu fragen. Wenn Sie wissen möchten, was erforderlich ist, um Ihre Arbeit gemäß den Unternehmensrichtlinien zu erledigen, Fragen Sie Ihren Chef, nicht uns. Die Antwort auf Ihre zweite Frage lautet: Ja, die statische Analyse ist äußerst effektiv. Vollständige Offenlegung: Ich entwerfe statische Analysatoren.

    – Eric Lippert

    15. April 2014 um 17:07 Uhr


  • Wenn Sie mir nicht glauben wollen, verwenden Sie die Wissenschaft, um Ihre zweite Frage zu beantworten. Holen Sie sich zehn Millionen Codezeilen, beheben Sie alle Compiler-Warnungen und lassen Sie ihn dann durch eine Reihe statischer Analysatoren laufen. Überprüfen Sie alle erzeugten Fehler. Wenn es einen statischen Analysator gab, der einen echten positiven Fehler erzeugte, den Ihr Compiler nicht hatte, war er beim Auffinden von Fehlern effektiver als Ihr Compiler. Unsere Experimente zeigen, dass Sie in einer typischen Codebasis damit rechnen können, pro tausend gescannter Codezeilen etwa einen schwerwiegenden Fehler zu finden.

    – Eric Lippert

    15. April 2014 um 17:11 Uhr

Kurze Antwort: Ja.

Lange Antwort: Compiler werden in der Tat besser darin, bestimmte Arten von “Fehlern” zu analysieren, aber die “Tiefe”, mit der sie arbeiten, ist normalerweise viel geringer als die richtigen Werkzeuge dafür. Insbesondere Tools, die über Kompiliereinheiten hinweg funktionieren, wie Coverity, die (zum Beispiel) verstehen können, dass eine Funktion einen Zeiger als zurückgeben kann NULLund wenn dies der Fall ist, stürzt Ihr Code ab, da Sie nicht nachsehen NULL vor dem Zugriff auf den Zeiger.

Statische Analysetools können auch die Verwendung von Sperren überprüfen, was der Compiler normalerweise nicht kann.

Wie effektiv es wirklich ist, hängt davon ab, welches Tool Sie verwenden, welche Einstellungen und wie gut Sie den Code ansonsten testen. Also kommt auch “Code Coverage” ins Spiel. Gehen Sie beim Testen jeden Zweig Ihres Codes durch? Mit jedem möglichen Wert, der einen Unterschied im Verhalten bewirkt? Statische Analysetools können Fehler erkennen, die Ihre Tests möglicherweise nicht abdecken.

(Ob es in Ihrem speziellen Geschäft tatsächlich sinnvoll ist, ist natürlich eine ganz andere Diskussion – das müssen Ihr Chef und seine/ihre Chefs entscheiden.)

  • Ich frage mich nur, Sie haben nicht zufällig übersprungen Testen von Clang ccc-analyzer bevor Sie diese Antwort schreiben? Hier scheint die Kombination aus dem Wissen im Compiler-Backend und der statischen Analyse viel mächtiger zu sein als das Übliche lint Programm. Ich habe festgestellt, dass einige andere statische Analysetools, die nicht kostenlos sind, Clang- und LLVM-Funktionen ebenfalls ausgiebig nutzen.

    – 0xC0000022L

    15. April 2014 um 10:38 Uhr

  • Ich persönlich habe es nicht verwendet ccc-analyzer, aber es ist ein weiteres statisches Analysetool, das Sie der Liste hinzufügen könnten. Es ist jedoch immer noch ein separater Durchgang zum normalen Kompilieren (Es ist zufällig ein Teil von clangwird aber bei “normaler Kompilierung” nicht verwendet).

    – Mats Petersson

    15. April 2014 um 10:50 Uhr

  • es kann, muss aber nicht, ein separater Pass sein. Das Ergebnis wird in beiden Fällen immer noch binär sein. Meine Bemerkung wurde hauptsächlich durch die Behauptung ausgelöst, dass Compiler weniger Tiefe haben, ich würde argumentieren, dass es das Gegenteil ist. Hängt dann aber vom jeweiligen Tool ab. Ich denke, das Problem, das ich bei Ihrer Antwort sehe, ist die (IMO unangemessene) Verallgemeinerung.

    – 0xC0000022L

    15. April 2014 um 13:59 Uhr

  • Das Wort, das ich dort gesetzt habe, war “typisch”, was impliziert, dass “es möglicherweise nicht für jeden Compiler gilt” – dem stimme ich zu clang, mit den richtigen Durchgängen, kann in dieser Hinsicht viel mehr als die meisten Compiler. (Ich arbeite mit LLVM sowohl bei der Arbeit [not directly] und mit meinem Hobby-Pascal-Compiler, und ich benutze auch clang). Aber es gibt auch eine ganze Reihe anderer statischer Analysetools, die verschiedene andere Erkennungen ermöglichen, die derzeit nicht in Ordnung sind.

    – Mats Petersson

    15. April 2014 um 14:35 Uhr

  • Also habe ich gerade mein Compiler-Projekt mit ausgeführt clang++ --analyzerund abgesehen davon, dass es 13 Minuten dauert (ca. das 10-fache der normalen Zeit) und einen echten Fehler findet [and one where it clearly didn’t understand what was going on inside the stl libraries allocator implementation – variadic templates…]ich stimme dem “Sie könnten es mit Ihrer regulären Kompilierung ausführen” nicht zu – zumindest mit clang 3.5 von Ende März gibt es die Ergebnisse der Analyse als Ausgabe für aus -o somefile.o, was bedeutet, dass es nichts zu verknüpfen gibt. Ich würde das auch nicht jedes Mal ausführen wollen, wenn ich etwas kompiliere.

    – Mats Petersson

    15. April 2014 um 15:58 Uhr

Es ist nicht so, dass Compiler nicht die Analyse durchführen können, die statische Analysewerkzeuge leisten. Das Problem ist, dass die statische Codeanalyse viel Zeit in Anspruch nimmt und normalerweise nicht für jede einzelne Kompilierung benötigt wird. Compiler sind im Allgemeinen für ein ausgewogenes Verhältnis von Codequalität und Kompilierungszeit optimiert. Wenn ein Compiler zufällig auf einen Fehler in Ihrem Code stößt, wird er Sie darüber informieren, aber er hat keine Zeit, aktiv nach Fehlern zu suchen.

Benutzer-Avatar
Naab

Außerdem ist die statische Analyse wichtig, um Metriken zu generieren.

Diese Metriken können zeigen: zyklomatische Komplexität, die Tiefe Ihrer Klassenvererbung und viele andere / Abhängigkeitsdiagramm / % der Kommentare und vieles mehr (Verstehe hat zum Beispiel eine vollständige Liste der Funktionen ).

Ein guter Punkt ist auch, dass Sie mit den meisten statischen Analysetools spezifische Regeln hinzufügen können, die nützlich sein können, wenn Ihr Projekt / Unternehmen Codierungsregeln hat.

Sie können auch einen “Continuous Integration”-Server hinzufügen, der jeden Tag Ihren svn/git/other-Entwicklungszweig auscheckt und die Analyse nachts durchführt. Auf diese Weise können Sie am nächsten Tag den Code korrigieren, der nicht Ihrem Regelsatz entspricht.

Benutzer-Avatar
Da ich bin

Ja, es verleiht dem Code mehr Vertrauen.

MISRA-Regeln werden häufig in Echtzeitsystemen verwendet. Die Einhaltung von MISRA (durch Ausführen eines von Misra unterstützten Tools) wird von vielen Softwareprüfern verlangt.

Auch MISRA (oder ähnliche Standards) definieren einige umständliche Regeln, um Benutzer daran zu hindern, ausgefallene Dinge zu tun könnte schief gehen etwas Compiler. Zum Beispiel ist Zeigerarithmetik von MISRA verboten, aber kein Compiler wird Sie davor warnen.

BEARBEITEN:
Ein weiteres Beispiel: Der folgende Code tut, was viele Leute nicht erwarten (x != 1,1 wegen der Gleitkommagenauigkeit).

int main(int agrc, char** argv){

    float x = 1.1;
    if(x == 1.1)
        printf("Yes!\n");
    else
        printf("OMG!\n");
    return 0;
}

Dies wird von Compilern nicht erkannt (versucht auf gcc 4.6 und clang 3.2). Aber es wird von fast allen statischen Analysetools erkannt.

Gute statische Analysewerkzeuge analysieren Dinge wie zyklometrische Komplexität und sogar Dinge wie „Code Smells“ (siehe Martin Fowlers Refactoring-Buch). Sogar Zeilenzahlen in einer Datei oder in einer Funktion sind Hinweise darauf, dass Ihr Code verbessert werden kann. Ich glaube jedoch nicht, dass Lint diese Bereiche abdeckt.

Werden noch statische Analysetools benötigt? Unbedingt. Die von Compilern ausgegebenen Warnungen werden immer ausgefeilter, aber es gibt immer noch die Einschränkung, dass ein Compiler im Allgemeinen jeweils nur an einer Quelldatei arbeitet. Jede Datei wird kompiliert (*.c -> *.o), und die resultierenden Objektdateien werden am Ende miteinander verknüpft. Um eine wirklich effektive statische Analyse durchzuführen, müssen Sie die gesamte Codebasis auf einmal betrachten und einzelne Dateien sowie die Interaktionen zwischen ihnen analysieren. Compiler sind im Allgemeinen nicht so konzipiert, sodass einem Compiler allein normalerweise die Art von Dingen entgeht, die statische Analysatoren aufgreifen. Sie möchten diese Funktionalität nicht in den normalen Compiler einbauen, da dies eine ziemlich starke Auswirkung auf die Leistung hat. Eine statische Analyse, die in meinem aktuellen Projekt ausgeführt wird, dauert normalerweise viermal so lange wie eine normale Kompilierung. Sie möchten diesen zusätzlichen Overhead nicht bei jedem einzelnen Build, daher ist es am besten, ihn an ein separates, spezialisiertes Tool zu verlagern, das bei Bedarf ausgeführt werden kann (oder im Fall einiger moderner Compiler ein separater Satz von Befehlszeilenoptionen). die standardmäßig deaktiviert sind).

Wie effektiv ist die statische Analyse? Sehr. Mein Team findet eine große Anzahl potenzieller Probleme durch statische Analysetools, von denen die meisten mit anderen Methoden fast unmöglich zu finden wären. Es ist besonders gut geeignet, komplexe Probleme zu finden, die Menschen nicht gut erkennen können, wie z. B. solche, die die Wechselwirkung zwischen mehreren lokalen und globalen Variablen beinhalten. Selbst wenn Sie über eine hervorragende Testabdeckung verfügen, finden statische Analysatoren alle möglichen Dinge, die durch Tests allein schwer zu finden sind. Dies gilt umso mehr für die Embedded-Welt, wo das Testen tendenziell schwieriger und weniger automatisiert ist. Meiner Erfahrung nach haben uns statische Analysatoren sogar Probleme aufgezeigt, von denen wir nicht einmal wussten, dass wir sie überhaupt testen mussten.

Ich würde auf jeden Fall die Verwendung statischer Analysewerkzeuge für jedes nicht triviale Softwareprojekt empfehlen. Ich verwende tatsächlich zwei separate statische Analyseprogramme (einer ist in die Compiler-Suite integriert und der andere ist ein separates Dienstprogramm); Sie werden überrascht sein, was der eine fängt und der andere verfehlt. Ich empfehle dringend, dass Sie sich einen angepassten Satz von Regeln/Tests für Ihre Analyseläufe ausdenken, anstatt einfach einen Regelsatz wie MISRA zu übernehmen. Die Anforderungen jedes Projekts sind unterschiedlich, und viele branchenweite Spezifikationen wie MISRA enthalten viele Dinge, die für die meisten Menschen nicht erforderlich sind. Je mehr unnötige Dinge Sie überprüfen, desto länger dauert die Analyse, desto mehr Fehlalarme müssen Sie durchwühlen usw.

1142430cookie-checkMüssen wir noch statische Analysen durchführen? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy