Frage

Beachten Sie, dass es nicht um die .NET -CLR geht, die Microsoft in die Atmosphäre stößt, um das Konzept des verwalteten Code zu evangelisieren. Die meisten von Ihnen wissen, dass Managed Code schon seit einiger Zeit gibt und nicht sehr mit Raketenwissenschaft zusammenhängt.

Was ich wissen möchte, ist Warum das Konzept der Laufzeitsicherheit in der Entwicklung von Computern so spät kam.

Ich weiß, dass dies so ist, als würde man fragen: "Warum ist das erste Modell T Ford nicht mit Airbags und Sicherheitsgurten gekommen?". Die Relevanz der Frage steht trotzdem immer noch, denn es liegt in der menschlichen Natur, erneut bekannte Gefahren zu schützen. ZB Das erste T-Ford ging nicht schnell genug, um die Airbag-Forschung zu motivieren. Es ging nicht schnell genug für die Menschen, um so oft tödliche Urteilsfehler zu machen, dass es in vielen Ländern den Sicherheitsgurt als Gesetz und Standard motiviert.

In der Computerentwicklung ist es fast umgekehrt. Wir begannen mit Assembler, das entspricht dem Fahren eines T-Fordes mit einem Eyepatch mit einem Jahr 200 km / h. Ich hatte das Vergnügen, mich mit ein paar alten Truckern aus dieser Zeit zu unterhalten und diese Geschichten über Handassemblierungscode, menschliche Debugger, Grillionen Code usw. zu hören, wenn wir einen wirklich bösen Fehler in C machen, könnten wir am Ende enden mit einem Bluescreen. Vor Jahrzehnten konnten Sie mit beschädigter Hardware enden und Gott weiß was. Aber es ist ein Rätsel für mich - so viele Jahrzehnte, und alles, was wir getan haben, um das Absturz weniger schmerzhaft zu machen, war der Bluescreen (Entschuldigung, MS als Archetyp für irgendetwas zu verwenden).

Es ist nicht nur innerhalb der menschlichen Natur, vor bekannten Gefahren zu schützen, Es liegt auch in der Natur eines Programmierers, gemeinsame Einrichtungen zu automatisieren und zu systemisieren, wie Fehlerprüfung, Speicherdiagnose, Protokollierungsrahmen, Sicherungswartung usw. usw.

Warum haben Programmierer/Menschen nicht begonnen, die Aufgabe zu automatisieren, sicherzustellen, dass der Code, den sie dem System füttern, dem System nicht schädigen wird. Ja, natürlich, Leistung. Aber hey, das war gut, bevor ein ernsthaft durchdringender Hardware -Standard. Warum wurden Motherboards nicht mit Busarchitekturen und zusätzlichen Prozessoren gestaltet, um den "verwalteten Code" zu erleichtern?

Gibt es eine Metapher, um T -Fords nicht schnell genug zu sein, was ich fehlt?

War es hilfreich?

Lösung

Denken wir dies aus den ersten Prinzipien durch.

Eine verwaltete Plattform bietet einen relativ sandkäfigen Bereich, um den Programmcode auszuführen, der von der hochstufigen Sprache zu einem Formular erstellt wird, das besser geeignet ist, die von der Plattform (IL -Bytecodes) ausgeführt werden können. Es gibt auch Versorgungsfunktionen wie Müllsammlung und Modulbeladung.

Denken Sie nun über eine native Anwendung nach - das Betriebssystem bietet einen relativ sandkäfigen Bereich (einen Prozess), der den Programmcode ausführt, der von einer hochstufigen Sprache auf ein Formular erstellt wird, das von der Plattform (X86 Opcodes) geeignet ist. Es gibt auch Versorgungsfunktionen wie Virtual Memory Management und Modulladen.

Es gibt keinen großen Unterschied, ich denke, der Grund, warum wir die Plattform in erster Linie verwaltet haben, liegt einfach darin, dass das Codieren der Plattform erleichtert wird. Es sollte den Code zwischen OSS tragbar machen, aber MS kümmerte sich nicht darum. Sicherheit ist Teil der verwalteten Plattform, sollte aber Teil des Betriebssystems sein - z. Ihre verwaltete App kann wie ein normaler Prozess ähnlich und ähnlich schreiben. Wenn Sie dies einschränken, ist dies ein Sicherheitsfunktion, ist kein Aspekt einer verwalteten Plattform, die auf nativen nicht vorhanden ist.

Letztendlich hätten sie all diese verwalteten Funktionen in eine Reihe von nativen Dlls investieren und die Idee des Zwischen -Bytecode, der stattdessen zum nativen Code kompiliert, verschrottet. "Managed" -Featuren wie GC ist auf nativen Haufen leicht möglich - siehe ein Beispiel im Boehm C ++ One.

Ich denke, MS hat es teilweise getan -Plattform -Codierung möglich, etwas, das MS nicht interessiert.

Warum haben wir also nicht von Anfang an verwalteten Code erhalten - denn all die Dinge, die Sie als Teil des "Managed" -Codes erwähnen, sind native Code. Managierte Plattformen, die wir heute haben, sind einfach eine zusätzliche Abstraktion über einer bereits abstrahierten Plattform. Auf hohen Sprachen haben sie mehr Funktionen hinzugefügt, um Sie vor sich selbst zu schützen. Pufferüberläufe gehören der Vergangenheit an, aber es gibt keinen Grund, warum sie in C nicht implementiert werden können, als C zum ersten Mal erfunden wurde. Es ist nur so, dass sie es nicht waren. Vielleicht scheinen diese Funktionen im Nachhinein zu fehlen, aber ich bin mir sicher, dass wir in 10 Jahren fragen werden, dass "Warum C# die offensichtlich nützliche Funktion XYZ nicht implementiert, wie wir es heute haben."

Andere Tipps

Managed Code, das in Sicherheit usw. eingebaut ist, gibt es schon lange.

In der ursprünglichen PC -Plattform gab es einfach keinen Platz dafür und es wurde später nie hinzugefügt.

Der ehrwürdige IBM -Mainframe hat seit den 70er Jahren die Adressierung, unantastbare Kernalbibliotheken, rollenbasierte Sicherheit usw. geschützt. Außerdem wurde der Assembler -Code von einem ausgefeilten (für die Zeit) Änderungsmanagementsystem verwaltet. (Univac, Burroughs usw. hatte etwas Ähnliches.)

Unix hatte von Anfang an eine ziemlich anständige Sicherheit eingebaut (und es hat sich im Laufe der Jahre nicht sehr verändert).

Ich denke also, dass dies ein Problem mit Windows/Web Space ist.

Es gab noch nie ein Mainframe -Virus! Die meisten Finanztransaktionen in der Welt durchlaufen diese Systeme irgendwann, so dass es nicht so ist, als ob sie ein attraktives Ziel wäre.

Das interne IBM -Mail -System hat jedoch den ersten 'Trojaner' gehostet!

Tatsächlich gibt es schon sehr lange verwaltete Code. In Betracht ziehen:

  • LISPELN
  • Smalltalk
  • Basic (Originalgeschmack)

Alle stellten operativen systemähnlichen Umgebungen bereit, die die Verwendung von Speicher- und anderen Problemen mit Ressourcensteuerung schützten. Und alle waren relative Ausfälle (Basic war nur wirklich erfolgreich, wenn Merkmale wie Peek & Poke es Ihnen ermöglichten, sich mit dem zugrunde liegenden System einzulegen).

Computer waren nicht leistungsstark genug und es war zu teuer genug, sie leistungsfähig genug zu machen. Wenn Sie nur begrenzte Ressourcen zur Verfügung haben, zählt jedes Byte- und CPU -Zyklus.

Der erste Computer, den ich verwendete, war a Sinclair ZX -Spektrum 1982 hatte es weniger RAM (16K) als die Größe einer einzigen Windows -Schriftdatei heute. Und das war relativ in jüngster Zeit im Heimcomputeralter. Vor Mitte der 1970er Jahre war die Idee, einen Computer in Ihrem Haus zu haben, unvorstellbar.

Nur für die Aufzeichnung, wir haben nie die Hand zusammengestellt. Wir haben uns mit Assembler-Sprachcode von Hand zusammenhalten. Nun, das ist klar ...

Ihre Analogie trübt die Frage, da die Geschwindigkeit des Autos in diesem Sinne nicht analog zur Geschwindigkeit des Computers ist: Die zunehmende Geschwindigkeit des Autos erforderte die Änderungen der Autosicherheit, aber es ist nicht die erhöhte Geschwindigkeit des Computers, die das antreibt Bedarf an Änderungen der Computersicherheit ist die Zunahme der Konnektivität. Aus einem etwas anderen Blickwinkel: Für das Auto ist die zunehmende Geschwindigkeit die Fahren Technologie zur Erhöhung der Sicherheit. Für Computer ist die Erhöhung der Geschwindigkeit die Aktivieren Technologie zur Erhöhung der Sicherheit.

Die ersten Autos waren also in Unfällen sicher, weil sie langsam waren. Die ersten Computer waren in Sicherheit, weil sie nicht vernetzt waren.

Jetzt werden Autos durch Sicherheitsgurte, Airbags, ABS, Antikollisionsgeräte usw. sicherer. Computer werden durch zusätzliche Techniken sicher gemacht, obwohl Sie das Netzwerkkabel immer noch nicht schlagen können.

Dies ist eine Vereinfachung, aber ich denke, es steht im Mittelpunkt. Wir brauchten dieses Zeug damals nicht, weil Computer nicht mit dem Netzwerk verbunden waren.

Der gleiche Grund, warum es vor 300 Jahren keine Züge gab. Der gleiche Grund, warum es vor 30 Jahren keine Handys gab. Der gleiche Grund, warum wir immer noch keine Teleportationsmaschine haben.

Die Technologie entwickelt sich im Laufe der Zeit, sie wird als Evolution bezeichnet.

Die Computer waren damals nicht leistungsfähig genug. Wenn Sie einen Müllsammler im Hintergrund ausführen, hat Sie die Anwendungsleistung getötet.

Im Gespräch mit Ihrer Frage, warum Computer die Schutzmechanismen auf der Ebene des verwalteten Code nicht hatten, und nicht, warum VMs nicht auf langsamer Hardware ausgeführt werden konnten (bereits in anderen Beiträgen erklärt). Die kurze Antwort ist, dass es war. CPUs sollten eine Ausnahme ausführen, wenn ein schlechter Code stattfand, damit er das System nicht beschädigen würde. Windows verarbeitet das notorisch schlecht, aber da draußen gibt es andere OSS. Unix gibt es als Signale vorbei, damit die Programme beendet werden, ohne das System zu senken. Egal, ob Sie verwalteten Code ausführen oder nicht, eine Null -Zeiger -Ausnahme ergibt sich genauso - in der Programmabschluss. Virtual Memory sorgt dafür, dass Programme nicht mit anderen Code herumspielen, sodass sie sich nur selbst verletzen können.

Das bringt mich zu meinem zweiten Punkt. All dies ist unnötig, wenn Sie wissen, was Sie tun. Wenn ich meine Möbel sauber halten möchte, lasse ich einfach kein Essen darauf fallen. Ich muss mein Haus nicht in Plastik bedecken, ich muss nur vorsichtig sein. Wenn Sie ein schlampiger Kodierer sind, der die beste VM der Welt nicht retten wird, können Sie nur Ihren schlampigen Code ohne Geräusche ausführen. Der Portierungscode ist auch einfach, wenn Sie eine ordnungsgemäße Kapselung verwenden. Wenn Sie ein guter Codierer sind, hilft der verwaltete Code nicht ausführlich. Deshalb benutzt es nicht jeder. Es ist einfach eine Frage der Präferenz, nicht besser / schlechter.

Was die Laufzeitsicherheit betrifft, kann ein P-Code-Compiler nichts vorhersagen, dass ein Maschinencode nicht kann, und nichts, was ein verwalteter Code-Interpreter mit dem Betriebssystem nicht bewältigen kann, das das Betriebssystem bereits kann (oder nicht). Motherboards mit zusätzlichen Bussen, CPUs und Anweisungssätzen kosten viel mehr Geld - es dreht sich alles um das Kosten -Leistungs -Verhältnis.

1970 waren die Speicherkosten ungefähr 1 $/Bit (ohne Inflation). Sie können sich die Luxusmüllsammlung nicht mit solchen Kosten leisten.

Ich denke wie die meisten Fragen: "Warum hatten wir nicht X in der Programmierung vor Jahren?" Die Antwort ist Geschwindigkeits-/Ressourcenzuweisung. Mit begrenzten Ressourcen mussten sie so effektiv wie möglich verwaltet werden. Der mit dem Managed Code im Zusammenhang mit dem Managed Code verbundene allgemeine Zweck wäre zu ressourcenverbrauch gewesen, um in leistungskritischer Anwendungen der Zeit von Vorteil gewesen zu sein. Dies ist auch ein Teil dessen, warum der heutige leistungskritische Code immer noch in C, Forran oder Assembler geschrieben ist.

Warum bauten wir nicht einfach Flugzeuge und Raumschiffe gleichzeitig, anstatt mit Pferde-und-Carriage und all dem mühsamen Zeug herumzuschlagen?

Die Verwendung einer Zwischensprache erfordert eines von zwei Dingen:

  1. Laufzeit-Interpretation, die eine erhebliche Leistungsstrafe hat (weithin variabel-gleichzeitig 2x oder weniger, aber manchmal 100x oder mehr)
  2. Ein Just-in-Time-Compiler, für den zusätzlichen RAM erforderlich ist und die Verzögerung in etwa proportional zur Programmgröße erhöht, anstatt die Anzahl der ausgeführten Aussagen

Eine Sache, die sich im Laufe der Jahre geändert hat, ist, dass viele Programme die am stärksten verwendeten Teile ihres Modus mehrmals als früher ausführen. Angenommen, das erste Mal, dass eine bestimmte Aussage ausgeführt wird, wird eine Strafe von 1.000 Mal so lange wie nachfolgende Hinrichtungen anfallen. Wie wirkt sich diese Strafe in einem Programm aus, bei dem jede Aussage durchschnittlich 100 Mal ausgeführt wird? Wie wirkt sich diese Strafe auf ein Programm aus, bei dem jede Aussage durchschnittlich 1.000.000 Mal ausgeführt wird?

Just-in-Time-Kompilierung war seit langem möglich, aber in den 1980er oder 1990er Jahren wären die Leistungskosten inakzeptabel gewesen. Da sich die Technologien geändert haben, sind die praktischen Kosten der JIT -Zusammenstellung so weit gekommen, dass sie völlig praktisch sind.

Die Antwort wird klarer - Menschen wurden nicht für das Schreiben von Programmen gebaut. Maschinen sollten es tun und uns entspannen lassen, indem wir Pacman spielen.

Für das, was es wert ist, habe ich ein paar Papiere für meine Rechensprachenklasse (eine von Car Hoare und eine von Nicholas Wirth) gelesen, die genau dies in den 60er und 70ern unter anderem befürwortet.

Ich kann nicht genau sprechen, warum diese Dinge nicht passiert sind, aber ich vermute, dass es nur eines der Dinge ist, die im Nachhinein offensichtlich aussehen, das damals nicht offensichtlich war. Es ist nicht so, dass frühere Compiler nicht über Sicherheit besorgt waren. Es war so, dass sie unterschiedliche Ideen hatten, wie man das macht.

Hoare erwähnt die Idee eines "Checkout Compiler". Soweit ich das beurteilen kann, ist dies im Wesentlichen ein Compiler, der eine statische Analyse durchführt. Für ihn war dies eine beliebte Technik, die fehlschlug (oder zumindest nicht so viele Probleme gelöst hat, wie sie gelöst wurde). Die Lösung für ihn bestand darin, Programmiersprachen sicherer zu machen, indem er verwalteten Code erstellt wird (oder zumindest hätte er ihn in moderner Hinsicht gestellt).

Ich würde mir vorstellen, dass die Idee des verwalteten Code, sobald C (und später C ++) aufgenommen wurde, im Wesentlichen tot war. Es ist nicht so, dass C eine schlechte Sprache war, nur dass es beabsichtigt war, eine Assemblersprache als eine Anwendungsprogrammiersprache zu sein.

Wenn Sie eine Chance bekommen, können Sie lesen Hinweise zum Programming-Sprachdesign. Es ist eine ziemlich gute Lektüre, wenn Sie sich für solche Dinge interessieren.

Die beste Antwort auf diese Frage ist, dass zu diesem Zeitpunkt niemand eine Vorstellung vom verwalteten Code hatte. Wissen entwickelt sich im Laufe der Zeit tatsächlich. Im Vergleich zu Feldern wie Architektur oder Landwirtschaft ist Informatik ein sehr junges Feld. Das kollektive Wissen über das Feld ist also auch jung und wird sich im Laufe der Zeit weiterentwickeln. Vielleicht stoßen wir in ein paar Jahren auf ein neues Phänomen und jemand wird die gleiche Frage stellen: "Warum hat jemand nicht an Xyz Beoor gedacht?".

Ich würde sagen, dass es größtenteils Veränderungswiderstand in Verbindung mit falscher Wahrnehmung der Ineffizienz der Müllsammlung war, die die Einführung von GC und verwandte Techniken verzögert. Natürlich hat das hirntote segmentierte Speichermodell auf Intel 8086 nicht genau dazu beigetragen, die Sane Memory Management auf dem PC zu fördern.

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