Domanda

Si noti che non si tratta del .NET CLR che Microsoft sta lanciando nell'atmosfera per evangelizzare il concetto di codice gestito.Molti di voi sanno che il codice gestito esiste da un po' di tempo e non è molto legato alla scienza missilistica.

Quello che vorrei sapere è perché il concetto di sicurezza runtime nell'evoluzione dei computer è arrivato così tardi.

So che è come chiedere "perché la prima Ford Modello T non era dotata di airbag e cinture di sicurezza?".Ciononostante l'attualità della questione rimane attuale, perché è nella natura umana proteggersi dai pericoli conosciuti.Per esempio.la prima T-Ford non andò abbastanza veloce da motivare la ricerca sugli airbag.Non è andata abbastanza veloce perché le persone commettessero errori di giudizio fatali così spesso da motivare l'uso delle cinture di sicurezza come legge e standard in molti paesi.

Nell'evoluzione dei computer è quasi il contrario.Abbiamo iniziato con l'assemblatore, l'equivalente di guidare una T-Ford a 200 miglia all'ora con una benda sull'occhio.Ho avuto il piacere di conversare con alcuni vecchi camionisti di quest'epoca, ascoltando queste storie sull'assemblaggio manuale del codice assembly, sui debugger umani, sulle righe di codice grillion ecc.Se commettiamo un errore davvero grave in C, potremmo ritrovarci con una schermata blu.Decenni fa, potevi ritrovarti con l'hardware danneggiato e Dio sa cosa.Ma per me è un mistero: sono passati così tanti decenni e tutto ciò che abbiamo fatto per rendere gli incidenti meno dolorosi è stato lo schermo blu (scusate se uso la SM come archetipo per qualsiasi cosa).

Non è solo nella natura umana proteggersi dai pericoli conosciuti, è anche nella natura di ogni programmatore automatizzare e sistematizzare le strutture comuni, come il controllo degli errori, la diagnostica della memoria, i framework di registrazione, la manutenzione del backup, ecc. Ecc.

Perché i programmatori/umani non hanno iniziato ad automatizzare il compito di garantire che il codice che inseriscono nel sistema non danneggi il sistema?.Sì, naturalmente, prestazione.Ma ehi, questo accadeva ben prima di qualsiasi standard hardware seriamente penetrante.Perché le schede madri non sono state progettate con architetture bus e processori aggiuntivi per facilitare il "codice gestito"?

C'è qualche metafora sul fatto che le Ford Modello T non siano abbastanza veloci che mi sfugge?

È stato utile?

Soluzione

Pensiamo questo attraverso da principi primi.

Una piattaforma gestita fornisce una zona relativamente sandbox per eseguire codice di programma che viene creato dal linguaggio ad alto livello ad una forma più adatta per essere eseguito dalla piattaforma (bytecode IL). Nel ci sono anche funzioni di utilità come la raccolta dei rifiuti e il modulo di carico.

Ora pensare a un'applicazione nativa - il sistema operativo fornisce un'area relativamente sandbox (un processo) per eseguire codice di programma che è stato creato da un linguaggio ad alto livello ad una forma più adatta per essere eseguito dalla piattaforma (codici operativi x86). In esistono anche funzioni di utilità come la gestione della memoria virtuale e caricamento del modulo.

Non c'è molta differenza, penso che il motivo siamo riusciti piattaforma in primo luogo è semplicemente perché rende la codifica la piattaforma più facile. Si dovrebbe rendere il portatile codice tra sistemi operativi, ma MS non ha la cura per questo. La sicurezza è parte della piattaforma gestita, ma dovrebbe essere parte del sistema operativo - ad es. la vostra applicazione gestito può scrivere file e simili, proprio come un processo normale. La limitazione che è una caratteristica di sicurezza, non è un aspetto di una piattaforma gestita che non esiste sul nativo.

In definitiva, avrebbero potuto mettere tutte quelle caratteristiche gestite in un insieme di DLL native e scartato l'idea del bytecode dell'intermediario, JIT compilazione in codice nativo, invece. caratteristiche "gestiti" come GC è facilmente possibile in cumuli nativi -. vedere il Boehm C ++ uno per esempio

Credo che MS ha fatto in parte perché ha fatto il compilatore più facile da scrivere, e in parte perché è così che Java è stato fatto (e .NET è molto un discendente di Java, anche se solo in spirito), anche se Java ha fatto in questo modo per fare cross-platform di codifica possibile, qualcosa che MS non si preoccupa per.

Quindi, perché non otteniamo codice gestito fin dall'inizio - perché tutte le cose di cui parli come facenti parte del codice di 'gestito', sono codice nativo. piattaforme gestite che abbiamo oggi sono semplicemente un'astrazione aggiuntivo sulla parte superiore di una piattaforma già estratta. linguaggi di alto livello hanno avuto più funzioni aggiunte a loro per proteggere l'utente da te stesso, buffer overflow sono una cosa del passato, ma non c'è alcuna ragione per cui non avrebbero potuto essere implementato in C quando C è stato inventato prima. Il suo solo che non lo erano. Forse il senno di poi fa sembrare come queste caratteristiche mancavano, ma sono sicuro che in 10 anni di tempo, saremo chiedendo "Perché non C # implementare la funzionalità ovviamente utile XYZ come abbiamo oggi"

Altri suggerimenti

Il codice gestito costruito in sicurezza, ecc è stato intorno per un lungo periodo di tempo.

Semplicemente non ci fosse spazio per essa nella piattaforma originale per PC e non è mai ottenuto aggiunta in un secondo momento.

Il mainframe IBM venerabile ha ha protetto l'indirizzamento, intoccabili librerie kernal, sicurezza basata ruolo ecc ecc fin dagli anni '70. Inoltre tutto ciò che il codice Assembler è stato gestito da una sofisticata (per l'epoca) sistema di gestione del cambiamento. (Univac, Burroughs ecc aveva qualcosa di simile.)

Unix ha avuto la sicurezza abbastanza decente costruito fin dall'inizio (e non è cambiato molto nel corso degli anni).

Quindi penso che questo è molto più un problema di spazio windows / web.

Non c'è mai stato un virus mainframe! La maggior parte delle transazioni finanziarie del mondo passano attraverso questi sistemi ad un certo punto quindi non è come se non fossero un bersaglio attraente.

Il sistema di posta IBM interna ha fatto ospiterà il primo 'trojan' però!

In realtà, il codice gestito è stato intorno per un tempo molto lungo. Prendere in considerazione:

  • LISP
  • Smalltalk
  • BASIC (sapore originale)

Tutti gli ambienti di sistema simile a condizione di funzionamento che proteggevano l'uso dalla memoria e altri problemi di controllo delle risorse. E tutti erano guasti relativi (BASIC veramente solo quando sono succeduti sono state introdotte funzionalità come PEEK e POKE che hanno permesso di pasticciare con il sistema sottostante).

I computer non erano abbastanza potenti e che li rende abbastanza potente era troppo costoso. Quando hai solo avuto risorse limitate a disposizione, ogni byte e CPU conteggi di ciclo.

Il primo computer che ho usato era un rel="nofollow Sinclair ZX Spectrum nel 1982. Aveva meno RAM (16K) rispetto alle dimensioni del file del carattere oggi una sola di Windows'. E che è stato relativamente recenti, nell'era del computer di casa. Prima metà degli anni 1970 l'idea di avere un computer in casa era inconcepibile.

assemblaggio

Per la cronaca, non abbiamo mai mano compilato. Abbiamo assemblato a mano il codice in linguaggio assembly. Ora che questo è chiaro ...

L'analogia è offuscando la questione perché la velocità della vettura non è analoga alla velocità del computer in questo senso: la velocità crescente della macchina ha richiesto i cambiamenti nella sicurezza auto, ma non è l'aumento della velocità del computer che spinge la necessità di cambiamenti nella sicurezza informatica, è l'aumento della connettività. Da un angolo leggermente diverso: Per l'auto, aumentando la velocità è il di guida la tecnologia per aumentare la sicurezza. Per i computer, aumentando la velocità è il abilitazione la tecnologia per aumentare la sicurezza.

Quindi, le prime vetture erano al sicuro in incidenti perché erano lenti. I primi computer erano al sicuro perché non erano in rete.

Ora, le auto sono resi più sicuri attraverso le cinture di sicurezza, airbag, ABS, dispositivi anti-collisione, e così via. I computer sono messi in sicurezza attraverso tecniche aggiuntive, anche se non è ancora possibile battere scollegare il cavo di rete.

Questa è una semplificazione, ma penso che arriva al cuore di essa. Non abbiamo bisogno di quella roba allora, perché i computer non erano collegati alla rete.

Lo stesso motivo per cui ci sono stati i treni a 300 anni fa. Lo stesso motivo per cui ci sono stati i telefoni cellulari 30 anni fa. Lo stesso motivo per cui ancora non abbiamo la macchina di teletrasporto.

Tecnologia evolve nel corso del tempo, si chiama evoluzione.

I computer non era abbastanza potente allora. l'esecuzione di un garbage collector sullo sfondo avrebbe uccidere le prestazioni delle applicazioni.

Parlando alla tua domanda sul perché i computer non avevano i meccanismi di protezione a livello di codice gestito, piuttosto che il motivo per cui le macchine virtuali non poteva girare su hardware lento (già spiegato in altri post). La risposta breve è che è stato. CPU sono state progettate per un'eccezione quando il codice cattivo è accaduto in modo che non avrebbe danneggiato il sistema. Windows gestisce questo notoriamente poco, ma ci sono altri sistemi operativi là fuori. Unix passa come segnali in modo che i programmi vengono chiuse senza portare il sistema. Davvero se o non si esegue codice gestito o no, un'eccezione di puntatore nullo comporterà allo stesso modo - la chiusura del programma. La memoria virtuale garantisce che i programmi non si scherza con altro codice, in modo tutto quello che possono fare è farsi male.

Il che mi porta al secondo punto. Tutto questo non è necessaria se si sa cosa si sta facendo. Se voglio mantenere i miei mobili pulito, semplicemente non cadere cibo su di esso. Non ho bisogno di coprire la mia casa in plastica, devo solo stare attento. Se sei un coder sciatta il miglior VM nel mondo non sta per risparmiare, sarà solo permetterà di eseguire il codice sciatta, senza alcun rumore. Inoltre, il porting del codice è facile se si utilizza una corretta incapsulamento. Quando sei un buon programmatore, codice gestito non aiuta molto. Ecco perché non tutti lo utilizza. E 'semplicemente una questione di preferenza, non meglio / peggio.

Per quanto riguarda la sicurezza in fase di esecuzione va, non c'è niente di un compilatore codice P può prevedere che un codice macchina non può, e non un codice interprete gestito in grado di gestire che il sistema operativo non può (o non fa) già . Schede madri con autobus, CPU e istruzione set supplementare costano molto di più soldi - è interamente circa il rapporto costo / prestazioni

.

Nel 1970, il costo della memoria era di circa $ 1 / bit (senza inflazione). Lei non può permettersi la raccolta dei rifiuti di lusso con costi del genere.

Credo che come la maggior parte le domande: "Perché non ci siamo X nella programmazione Y anni fa", la risposta è di assegnazione di velocità / risorsa. Con risorse limitate che avevano bisogno di essere gestito nel modo più efficace possibile. Il tipo general purpose di gestione associata con il codice gestito sarebbe stato troppo consumo di risorse sia stata di beneficio in applicazioni critiche di prestazione del tempo. Questo è anche uno dei motivi per il codice critica la prestazione di oggi è ancora scritto in C, Fortran o assembler.

Perché non abbiamo costruito aeroplani e astronavi insieme, invece di perdere tempo con carrozze e tutta quella roba noiosa?

L'uso di un linguaggio intermedio richiede una delle due cose:

  1. interpretazione di run-time, che avrà una penalizzazione delle prestazioni sostanziale (ampiamente variabile - di tanto in tanto 2x o meno, ma a volte 100x o più)
  2. Un compilatore just-in-time, che richiederà RAM in più, e che andrà ad aggiungersi ritardo approssimativamente proporzionale alla dimensione del programma, piuttosto che il numero di istruzioni eseguite

Una cosa che è cambiata nel corso degli anni è che molti programmi eseguiti parti più pesantemente utilizzati di loro modo molte più volte rispetto al passato. Supponiamo che la prima volta che qualsiasi dichiarazione particolare viene eseguita una penale di 1.000 volte più a lungo successive esecuzioni. Quale sarà l'effetto di tale pena in un programma in cui ogni istruzione viene eseguita una media di 100 volte? Quale sarà l'effetto di tale sanzione in un programma in cui ogni istruzione viene eseguita una media di 1.000.000 volte?

Just-in-time compilazione e 'stato possibile per molto tempo, ma nel 1980 o 1990, il costo delle prestazioni sarebbe stato inaccettabile. Poiché le tecnologie sono cambiate, i costi pratici di compilazione JIT sono scesi a tal punto che sono del tutto pratico.

La risposta diventa più chiaro - gli esseri umani non sono stati costruiti per i programmi di scrittura. Macchine dovrebbero essere farlo e lasciando a rilassarsi giocando pacman.

Per quello che vale, ho letto un paio di articoli per la mia classe di lingue di calcolo (uno per CAR Hoare e un altro da Nicholas Wirth) sostenendo esattamente questo ritorno negli anni '60 e '70 tra le altre cose.

Non posso parlare esattamente il motivo per cui queste cose non è accaduto, ma la mia ipotesi è che è solo una di quelle cose che sembra evidente col senno di poi che non era evidente al momento. Non è che i compilatori precedenti non erano preoccupati per la sicurezza. E 'che avevano idee diverse su come fare questo.

Hoare menziona l'idea di un "compilatore checkout". Per quanto posso dire, questo è essenzialmente un compilatore che fa l'analisi statica. Per lui, questa era una tecnica popolare che non è riuscita (o almeno non ha risolto tanti problemi come è stato inteneded da risolvere). La soluzione per lui era di rendere i linguaggi di programmazione più sicuro con la creazione di codice gestito (o almeno è così che avrebbe dirla in termini moderni).

Mi immagino che una volta C (e poi C ++) preso piede, l'idea di codice gestito era essenzialmente morto. Non è che C è un linguaggio di male, solo che è stato destinato ad essere un linguaggio assembly, piuttosto che un linguaggio di programmazione di applicazione.

Se si ha la possibilità, si potrebbe leggere Suggerimenti sulla programmazione-linguaggio di design . E 'una buona lettura, se siete interessati a questo genere di cose.

Miglior risposta a questa domanda è, secondo me, nessuno aveva un'idea di codice gestito in quel momento. La conoscenza in realtà si evolve nel tempo. Rispetto a campi come l'architettura o l'agricoltura, l'informatica è un campo molto giovane. Così la conoscenza collettiva sul campo è anche giovane e si evolverà nel corso del tempo. Forse tra qualche anno ci imbattiamo in qualche nuovo fenomeno e qualcuno sarà la stessa domanda, "perché non qualcuno pensa di XYZ beofore?".

Direi che è stato in gran parte la resistenza cambiamento accoppiato con falsa percezione di inefficienza della raccolta dei rifiuti che ha ritardato l'adozione di GC e tecniche correlate. Naturalmente la morte cerebrale segmentato modello di memoria su Intel 8086 non ha esattamente contribuire a promuovere la gestione della memoria sana di mente sul PC.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top