Frage

Während auf ein neues Projekt arbeitet, wurde ich von einem Kunden QA representitive besucht, die mir eine Frage gestellt, die ich nicht wirklich vor in Betracht gezogen hatte:

  

Wie wissen Sie, dass die Compiler Sie verwenden Maschinencode erzeugt, der den C-Code Funktionalität genau übereinstimmt und dass der Compiler ist vollständig deterministisch?

Auf diese Frage hatte ich absolut keine Antwort, wie ich immer den Compiler für selbstverständlich genommen haben. Es dauert in Code und Maschinencode spuckt. Wie kann ich mich über und Test, dass der Compiler nicht tatsächlich Funktionalität hinzufügen, die ich nicht gefragt habe? oder sogar gefährlicher Code auf eine etwas andere Art und Weise, dass die Umsetzung, die ich erwarten?

Ich bin mir bewusst, dass diese perhapse nicht wirklich ein Problem ist für jeden etwas dabei, und in der Tat könnte die Antwort einfach sein ... „Sie sind über einen Lauf und mit ihr umgehen“. Wenn jedoch in einer eingebetteten Umgebung arbeiten, vertrauen Sie Ihren Compiler implizit. Wie kann ich mich beweisen und QA, dass ich Recht hat dabei?

War es hilfreich?

Lösung

Für sicherheitskritische eingebettete Anwendung Zertifizierungsstellen erfordern die „bewährte-in-use“ Voraussetzung für den Compiler zu erfüllen. Es sind in der Regel bestimmte Anforderungen (wie eine Art „Betriebsstunden“), die durch eine ausführliche Dokumentation erfüllt und nachgewiesen werden müssen. Doch entweder die meisten Menschen können nicht oder wollen nicht diese Anforderungen erfüllen, weil es sehr schwierig sein kann, vor allem auf Ihrem erstes Projekt mit einem neuen Ziel / Compiler.

Ein weiterer Ansatz ist im Grunde gar nicht dem Compiler der Ausgabe zu vertrauen. Jeder Compiler und auch sprachabhängig (Anhang G des C-90-Standard, anyone?) Mangel müssen durch eine strenge Reihe von statischer Analyse, fonds- und Deckung Tests zusätzlich zu der späteren Funktionsprüfung abgedeckt werden.

Ein Standard wie MISRA-C kann helfen, den Eingang zu beschränken an den Compiler zu einem „sicheren“ Teilmenge der C-Sprache. Ein weiterer Ansatz ist die Eingabe in einen Compiler auf eine Teilmenge einer Sprache zu beschränken und testen, wie die Ausgabe für die gesamte Teilmenge ist. Wenn unsere Anwendung nur aus den Komponenten aus der Untergruppe aufgebaut wird, wird angenommen, bekannt sein, wie die Ausgabe des Compilers sein wird. Das geht in der Regel durch „Qualifikation des Compilers“.

Das Ziel all dies ist in der Lage sein, die QS-Vertreter zu beantworten mit „Wir setzen nicht nur auf Determinismus des Compilers aber das ist die Art, wie wir es beweisen ...“.

Andere Tipps

Sie können dieses Argument auf jeder Ebene anwenden: vertrauen Sie die Bibliotheken von Drittanbietern? beurteilen Sie die OS vertrauen? haben Sie den Prozessor vertrauen?

Ein gutes Beispiel dafür, warum dies ein berechtigtes Anliegen natürlich sein kann, ist, wie Ken Thompson eine Backdoor in das ursprüngliche ‚login‘ Programm setzen ... und modifiziert, um den C-Compiler, so dass selbst wenn Sie Sie neu kompiliert anmelden noch die bekam Hintertür. Sehen Sie diese Posting mehr Details.

ähnliche Fragen wurden über Verschlüsselungsalgorithmen erhöht - wie wir wissen, gibt es in DEM kein Backdoor für die NSA ist durch herumzuschnüffeln

Am Ende der Sie müssen entscheiden, ob Sie die Infrastruktur vertrauen Sie auf genug bauen nicht darum zu kümmern, sonst müssen Sie Ihre eigenen Silizium-Chips zu entwickeln beginnen!

Sie wissen von Tests. Wenn Sie testen, Sie testen Ihre beiden Codes und die Compiler.

Sie werden feststellen, dass die Chancen, dass Sie oder der Compiler Schriftsteller einen Fehler gemacht haben, sind viel kleiner als die Wahrscheinlichkeit, dass Sie einen Fehler machen würden, wenn Sie das Programm in Frage in irgendeiner Assemblersprache geschrieben.

Es gibt Compiler Validierung Anzüge zur Verfügung.
Der, den ich erinnere mich ist "Perennial" .

Wenn ich auf einem C-Compiler für einen eingebetteten SOC Prozessor arbeite wir die Compiler gegen diesen und zwei weitere Validierung Anzüge zu validieren hatten (das ich den Namen vergessen). Validieren der Compiler auf ein gewisses Maß an Übereinstimmung mit diesen Test Anzügen war Teil des Vertrages.

Es läuft alles zu vertrauen. Hat Ihr Kunde jeden Compiler vertrauen? Verwenden, die, zumindest zwischen dem Ausgangscode Ihres und ihrem vergleichen.

Wenn Sie aber nicht vertrauen, ist es eine Referenz-Implementierung für die Sprache? Könnten Sie sie davon überzeugen, ihm zu vertrauen? Dann vergleichen Sie Sie gegen die Referenz oder die Referenz verwendet werden.

Dies alles vorausgesetzt, Sie tatsächlich den eigentlichen Code überprüfen Sie vom Verkäufer / Anbieter erhalten und dass Sie den Compiler überprüfen hat nicht manipuliert wurde, was der erste Schritt sein sollte.

Wie auch immer diese bleibt aber die Frage, wie würden Sie überprüfen, ohne Referenzen, einem Compiler, von Grund auf neu. Das sieht sicher wie eine Tonne Arbeit und erfordert eine Definition der Sprache, die nicht immer verfügbar ist, manchmal ist die Definition der Compiler.

  

Wie wissen Sie, dass die Compiler Sie verwenden Maschinencode erzeugt, der den C-Code Funktionalität genau übereinstimmt und dass der Compiler ist vollständig deterministisch?

Sie dies nicht tun, das ist, warum Sie die resultierende binäre testen, und warum Sie sicherstellen, die gleiche binäre Schiff mit Ihnen getestet. Und warum, wenn Sie ‚kleine‘ Software-Änderungen vornehmen, Regressions- Sie Test brach sicher, dass keiner der alten Funktionalität zu machen.

Die einzige Software, die ich habe, ist zertifiziert Avionik. FAA-Zertifizierung ist nicht genug rigoros die Software richtig funktioniert zu beweisen, während zur gleichen Zeit, die Sie nicht zwingen, durch eine bestimmte Menge von Reifen zu springen. Der Trick ist, Ihren ‚Prozess‘ zu strukturieren, so dass es Qualität so weit wie möglich verbessert, mit möglichst wenig Fremd hoop-Springen wie man sich erlauben kann. Also alles, was Sie wissen, ist wertlos und wird nicht wirklich Fehler finden, können Sie wahrscheinlich Wiesel aus. Und alles, was Sie wissen sollten Sie tun, weil es wird finden Fehler, die nicht ausdrücklich von der FAA verlangt wird, ist Ihre beste Wette Worte zu verdrehen, bis es klingt wie Sie die FAA / Ihren QA geben Menschen, was sie gefragt.

Dies ist eigentlich nicht so unehrlich wie ich gemacht habe es klingen in der Regel die FAA kümmert sich mehr um Sie gewissenhaft und sicher sein, dass Sie versuchen einen guten Job zu tun, als über was genau Sie tun.

Einige intellektuelle Munition könnten in Crosstalk, einem Magazin für die Verteidigung Software-Ingenieure zu finden. Diese Frage ist die Art der Sache, die sie auf viele wachen Stunden verbringen. http://www.stsc.hill.af.mil/ Übersprechen / 2006/08 / index.html (Wenn ich meine alte Notizen aus einem alten Projekt finden, ich werde wieder hier ...)

Sie können nie vollständig den Compiler vertrauen, auch sehr zu empfehlen diejenigen. Sie könnten ein Update veröffentlichen, die einen Fehler hat, und Ihr Code kompiliert gleich. Dieses Problem wird verschärft, wenn alten Code mit dem Buggy Compiler aktualisieren, Tests zu tun und die Ware nur Versand aus den Kunden Ring Sie 3 Monate später mit einem Problem haben.

Alles zum Testen kommt zurück, und wenn es eine Sache, die ich gelernt habe, ist es zu thouroughly Test nach jeder nicht-trivialen Änderung. Wenn das Problem bei dem kompilierten Assembler einen Blick zu finden, unmöglich scheint und überprüft es tut, was es tun soll.

Bei mehreren Gelegenheiten habe ich Fehler im Compiler gefunden. Einmal gibt es einen Fehler, bei den 16-Bit-Variablen würden erhöht erhalten, aber ohne Übertrag und nur dann, wenn der 16-Bit-Variable war Teil einer extern Struktur in einer Header-Datei definiert.

  

... Sie vertrauen Ihrem Compiler implizit

Sie werden feststellen, dass das erste Mal zu tun stoppen Sie über einen Compiler Fehler kommen. ; -)

Aber letztlich ist es das, was Tests sind für. Es ist nicht zu Ihrem Testregime Rolle, wie der Fehler in erster Linie auf Ihr Produkt erhielt in, alles, was zählt, ist, dass es nicht Ihre umfangreichen Prüfprogramm übergeben.

Nun .. Sie können nicht einfach sagen, dass Sie Ihren Compiler Ausgang vertrauen - vor allem, wenn Sie mit eingebettetem Code arbeiten. Es ist nicht schwer Diskrepanzen zwischen dem Code erzeugt zu finden, wenn Sie den gleichen Code mit verschiedenen Compilern kompilieren. Dies ist der Fall, weil der C-Standard selbst zu locker ist. Viele Details können ohne brechen den Standard von verschiedenen Compilern unterschiedlich implementiert werden. Wie gehen wir mit diesem Zeug umgehen? Wir vermeiden Compiler abhängige Konstrukte, wann immer möglich. Wir können damit umgehen, indem eine sicherere Teilmenge von C Auswahl wie Misra-C , wie zuvor durch den Benutzer cschol erwähnt. Ich muss nur selten den Code durch den Compiler erzeugt inspizieren, aber das hat auch manchmal mit mir passiert. Aber letztlich, Sie auf Ihren Tests, um angewiesen sind, um sicherzustellen, dass der Code wie vorgesehen verhält.

Gibt es eine bessere Möglichkeit gibt? Einige Leute behaupten, dass es gibt. Die andere Option ist der Code in SPARK / Ada rel="nofollow. Ich habe noch nie Code in SPARK geschrieben, aber mein Verständnis ist, dass Sie es immer noch gegen Routinen in C geschrieben verknüpfen würden, die mit den „Bare Metal“ Sachen beschäftigen würden. Die Schönheit der SPARK / Ada ist, dass Sie absolut garantiert werden, dass der Code von jedem Compiler erzeugt wird immer das gleiche sein wird. Keine Zweideutigkeit zu löschen. Obendrein erlaubt die Sprache, die Sie den Code mit Erklärungen, wie der Code dazu bestimmt ist, mit Anmerkungen versehen zu verhalten. Der SPARK-Toolset wird diese Anmerkungen verwendet formal zu beweisen, dass der Code geschrieben in der Tat nicht das tun, was die Anmerkungen beschrieben haben. So wurde mir gesagt, dass für kritische Systeme, SPARK / Ada eine ziemlich gute Wette ist. Ich habe es nie versucht, mich aber.

Sie wissen nicht sicher, dass der Compiler genau das tun, was Sie erwarten. Der Grund ist natürlich, dass ein Compiler ein Stückchen Software ist , und ist daher anfällig für Fehler.

Compiler Autoren haben den Vorteil, von einer hohen Qualität spec arbeiten, während der Rest von uns haben, um herauszufinden, was wir machen, wie wir entlang gehen. Allerdings Compiler-Spezifikationen auch haben Fehler und komplexe Teile mit subtilen Wechselwirkungen. Also, es ist nicht gerade trivial, um herauszufinden, was der Compiler tun soll.

Dennoch, wenn Sie entscheiden, was Sie die Sprache spec Mittel denken, können Sie einen guten, schnellt, automatisierten Test für jede Nuance schreiben. Dies ist, wo Compiler Schreiben einen großen Vorteil gegenüber schriftlich andere Arten von Software hat: in der Prüfung. Jeder Fehler wird ein automatisierter Testfall, und die Testsuite kann sehr gründlich. Compiler-Anbieter viel mehr Budget hat bei der Überprüfung der Richtigkeit des Compilers zu investieren, als Sie (Sie bereits einen Job haben, nicht wahr?).

Was bedeutet das für Sie? Es bedeutet, dass Sie sich mit den Möglichkeiten der Fehler in Ihrem Compiler offen sein müssen, aber die Chancen sind, werden Sie nicht sich selbst finden.

würde ich einen Compiler-Anbieter auswählen, das nicht wahrscheinlich ist, jederzeit schnell aus dem Geschäft zu gehen, die eine Geschichte von hohen Qualität in ihren Compiler haben, und dass ihre Fähigkeit (Patch) ihre Produkte Service unter Beweis gestellt hat. Compiler scheinen mehr richtig im Laufe der Zeit zu bekommen, so würde ich wählen, die um ein oder zwei Jahrzehnte gewesen sind.

Richten Sie Ihre Aufmerksamkeit auf Ihren Code richtig hinzubekommen. Wenn es klar und einfach , dann, wenn Sie tun einen Compiler Fehler getroffen, Sie haben gewonnen ‚t wirklich schwer zu denken, zu entscheiden, wo das Problem liegt. Schreiben Sie gute Unit-Tests , die sicherstellen, dass Ihr Code tut, was Sie es tun erwarten.

Versuchen Sie Unit-Tests.

Wenn das nicht genug ist, verschiedene Compiler verwenden und die Ergebnisse Ihrer Unit-Tests vergleichen. Vergleichen Strace Ausgänge, führen Sie Ihre Tests in einer VM, ein Protokoll von Festplatten- und Netzwerk-I / O, dann diejenigen vergleichen.

Oder schlagen Sie Ihren eigenen Compiler zu schreiben und ihnen sagen, was es geht kosten.

Das Sie leicht zertifizieren kann, ist, dass Sie einen untampered Compiler von Anbieter X verwenden Wenn sie nicht Anbieter X vertrauen, es ist ihr Problem (wenn X recht vertrauenswürdig ist). Wenn sie keine Compiler-Provider vertrauen, dann sind sie völlig unvernünftig.

Die Beantwortung ihrer Frage: Ich sicherstellen, dass ich einen untampered Compiler von X durch diese Mittel bin mit. X ist beliebter, plus Ich habe eine schöne Reihe von Tests, die unsere Anwendung zeigen verhält sich wie erwartet.

Alles andere beginnt die Dose von Würmern zu öffnen. Sie haben irgendwo zu stoppen, wie Rob sagt.

Manchmal tun Sie Verhaltensänderungen erhalten, wenn Sie aggressive Ebenen der Optimierung anfordern.

Und Optimierung und Gleitkommazahlen? Vergessen Sie es!

Für die meisten Software-Entwicklung (man denke an Desktop-Anwendungen) die Antwort wahrscheinlich ist, dass Sie nicht wissen, und kümmern sich nicht.

In sicherheitskritischen Systemen (man denke Kernkraftwerke und kommerzielle Avionik) Sie Sie Pflege und Regulierungsbehörden wird von Ihnen verlangen, es zu beweisen. Nach meiner Erfahrung kann man dies eine von zwei Möglichkeiten:

  1. einen qualifizierten Compiler verwenden, wobei „qualifiziert“ bedeutet, dass es nach den Standards von der Aufsichtsbehörde festgelegten überprüft wurde.
  2. Objekt-Code-Analyse durchführen. Im Wesentlichen Sie ein Stück Referenzcode kompiliert und dann manuell die Ausgabe analysiert, um zu zeigen, dass die Compiler alle Anweisungen nicht eingeführt haben, die nicht wieder auf den Quellcode zurückverfolgt werden kann.

Sie erhalten die ein Dijkstra schrieb.

Wählen Sie eine formal verifiziert Compiler, wie Compcert C-Compiler.

  1. Ändern der Optimierungsstufe des Compilers wird die Ausgabe ändern.
  2. Geringfügige Änderungen an einer Funktion kann der Compiler inline machen oder nicht mehr Inline-Funktion.
  3. Änderungen an den Compiler (gcc-Versionen zum Beispiel) kann die Ausgabe ändern
  4. Bestimmte Bibliotheksfunktionen können instrinic (d.h. optimierte emit assembly), während andere die meisten nicht.

Die gute Nachricht ist, dass für die meisten Dinge, die es spielt wirklich keine Rolle, dass viel. Wo dies der Fall, können Sie Montag zu prüfen, wenn es wirklich darauf ankommt (zum Beispiel in einer ISR).

Wenn Sie besorgt sind über unerwarteten Maschinencode nicht sichtbare Ergebnisse führt, ist der einzige Weg ist wahrscheinlich Compiler-Anbieter für die Zertifizierung von einer Art zu kontaktieren, die Ihre Kunden zufrieden stellen werden.

Ansonsten werden Sie es gleich wissen Sie über Bugs wissen in Ihrem Code -. Testen

Maschinencode von modernen Compiler kann sehr unterschiedliche und völlig unverständlich für mickrige Menschen sein.

Ich denke, es ist möglich, dieses Problem auf das Halting Problem zu reduzieren irgendwie.

Das offensichtlichste Problem ist, dass, wenn Sie irgendeine Art von Programm verwenden, um die Compiler und seinen Determinismus zu analysieren, wie Sie wissen, dass Ihr Programm korrekt kompiliert wird, und erzeugt das richtige Ergebnis?

Wenn Sie ein anderes verwenden, „sicher“ Compiler aber sie ist nicht sicher. Was ich bin sicher, ist ein Compiler von Grund auf neu zu schreiben wahrscheinlich ein einfacher Job wäre.

Auch eine qualifizierte oder zertifizierte Compiler kann zu unerwünschten Ergebnissen führen. Halten Sie Ihren Code einfach und Test, Test, Test. Die oder zu Fuß durch den Maschinencode von Hand, während keine menschlichen Fehler erlaubt. PLus das Betriebssystem oder was auch immer Umgebung, die Sie laufen auf (vorzugsweise kein Betriebssystem, nur Ihr Programm).

Dieses Problem wurde in unternehmenskritischen Umgebungen behoben seit Software und Compiler begann. Da viele der anderen, die geantwortet haben, auch wissen. Jede Branche hat ihre eigenen Regeln aus zertifizierten Compiler Programmierstil (Sie müssen immer so programmieren, nie diese oder jene oder die andere verwenden), viele Tests und Peer-Review. Überprüfen jeden Ausführungspfad, etc.

Wenn Sie nicht in einer dieser Branchen sind, dann bekommt man, was man bekommt. Ein kommerzielles Programm auf einem COTS-Betriebssystem auf COTS-Hardware. Es wird fehlschlagen, das ist eine Garantie.

Wenn Sie Ihre Sorgen um böswillige Bugs im Compiler, eine Empfehlung (IIRC, eine NSA Anforderung für einige Projekte) ist, dass der Compiler binären das Schreiben des Codes predate. Spätestens dann wissen Sie, dass niemand hat hinzugefügt Bugs gezielt in Ihre Programm.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top