Come possiamo essere certi che i componenti inferiori della programmazione del computer come compilatori, assemblatori, istruzioni della macchina, ecc. siano impeccabili?

58

Dal momento che stiamo diventando sempre più dipendenti dall'informatica, compresi i compiti molto critici della vita di tutti i giorni, mi stavo chiedendo come vengono testati quei componenti vitali.

Più tecnicamente, come vengono testati i compilatori e gli assemblatori? (Suppongo che ciò si riferisca a il problema di interruzione !!)

    
posta Sudip Bhandari 29.12.2015 - 16:38
fonte

8 risposte

105

Non puoi esserne certo, ma presumi che lo siano, finché non scopri che non lo sono. Ci sono stati molti bug in compilatori e hardware nel corso degli anni.

Il modo in cui vengono testati, ad esempio un compilatore, è che sono definiti in modo molto stretto e rigido, scritti attentamente, quindi testati con una enorme suite di test per verificare la correttezza. Aggiungete a ciò l'ampia base di utenti di un compilatore e verranno rilevati e segnalati altri bug. Una app per la programmazione degli appuntamenti dei dentisti, in confronto, ha molti meno utenti e meno ancora sono in grado di rilevare i difetti.

SQLite consiste di circa 73k linee di codice, mentre la sua suite di test consiste di circa 91378k righe di codice, più di 1250 volte quella di SQLite. Mi aspetto che i compilatori e altri strumenti di base abbiano rapporti simili. I processori oggi sono progettati essenzialmente con software, utilizzando linguaggi di descrizione dell'hardware come Verilog o VHDL e quelli con test software eseguiti su di essi, oltre a pin IO specializzati per l'esecuzione di test automatici al momento della produzione.

In definitiva si tratta di un gioco di probabilità, e test ripetuti e che coprono ampiamente la possibilità di spingere la probabilità di difetti a un livello accettabilmente basso, lo stesso di un altro progetto software.

    
risposta data 29.12.2015 - 20:07
fonte
46

In parole povere:

  1. Non puoi.
  2. I compilatori e gli interpreti sono testati unitamente a qualsiasi altro software (professionale).
  3. Un test di successo non significa che un programma sia privo di bug, significa solo che non sono stati rilevati errori.
  4. Una vasta base di utenti che usa il compilatore per un lungo periodo è un buon indicatore del fatto che ha pochissimi bug, perché gli utenti di solito testano casi a cui i progettisti non hanno pensato.
  5. Essere open source è anche un buon indicatore. "Con un numero sufficiente di bulbi oculari, tutti i bug sono superficiali ... Dato un beta-tester abbastanza grande e una base di co-sviluppatori, quasi tutti i problemi sarà caratterizzato rapidamente e la correzione sarà ovvia per qualcuno. ". Un compilatore closed-source potrebbe avere bug che insorgono in momenti molto specifici o che generano codice macchina meno che ottimale e la società dietro di esso potrebbe semplicemente non rivelare la loro esistenza e dare una priorità molto bassa nella road map del prodotto.

Bottom-line:

Direi di andare per OOP ( O ld, O penna e P opular). Ho appena inventato quell'acronimo.

    
risposta data 29.12.2015 - 20:01
fonte
24

Sono le tartarughe fino in fondo.

Nulla è certo. Non hai altra scelta che accontentarti delle valutazioni di fiducia.

Puoi considerarlo come una pila: Math > Fisica > Hardware > Firmware > Sistema operativo > Assemblatore / compilatore / etc

Ad ogni livello hai test che puoi eseguire per migliorare i tuoi punteggi di fiducia. Alcuni di questi test hanno la qualità delle prove formali, alcuni dei quali sono basati sull'osservazione, la maggior parte sono una combinazione di entrambi.

La parte difficile è svelare la ricorsione in alcuni di questi test perché usiamo programmi per fare prove e analisi osservative ora dove è diventato troppo difficile farlo a mano.

In definitiva però la risposta è che provi tutto quello che riesci a pensare. Analisi statica, fuzzing, simulazione, esecuzione con input estremi appositamente selezionati o input casuali, esecuzione / mappatura di ogni percorso di controllo, prove formali, ecc. Fondamentalmente il tuo obiettivo nel testing dovrebbe essere sempre quello di fare tutto il possibile per provare il tuo prodotto (es. chip / programma) non funziona come previsto. Se fai un vero sforzo e fallisci, puoi migliorare la tua valutazione di fiducia nella correttezza del tuo prodotto.

Il test è nel migliore dei casi un processo di semidecisione che significa che, dato che c'è un bug, lo troverai alla fine ma non puoi mai essere sicuro di averli trovati tutti. Anche con software verificati formalmente ti stai ancora affidando alla fisica, agli strumenti usati per eseguire le prove formali e che la cosa che hai dimostrato è necessaria e sufficiente affinché il tuo programma faccia ciò che è (spesso soggettivamente) "inteso". Per non parlare di tutti gli altri componenti che stai usando che non hanno prove formali.

    
risposta data 30.12.2015 - 05:55
fonte
17

Questa è una domanda "pericolosa" per i nuovi sviluppatori in quanto inizieranno a incolpare i loro strumenti invece del loro codice (è stato lì, fatto così, visto troppi farlo). Sebbene esistano bug in compilatori, ambienti runtime, sistema operativo, ecc., Gli sviluppatori dovrebbero essere realistici e ricordare che, finché non ci sono prove e test unitari che dimostrano il contrario, il bug è nel tuo codice .

In oltre 25 anni di programmazione in gran parte di C, C ++ e Java ho trovato:

  • due bug dovuti a un bug del compilatore (gcc e SunOS C)
  • circa una volta all'anno o due un bug a causa di un problema JVM Java (in genere correlato al consumo di memoria / raccolta dati inutili)
  • circa una volta al mese o due un errore in una libreria, che viene spesso corretto utilizzando la versione più recente o ripristinando la versione precedente della libreria

Tutti gli altri bug sono direttamente correlati a un bug o, più frequentemente, a una mancanza di comprensione di come funziona una libreria. A volte ciò che sembra essere un bug è dovuto a un'incompatibilità, ad esempio come è cambiata la struttura della classe Java che ha rotto alcune librerie AOP.

    
risposta data 30.12.2015 - 20:05
fonte
8

Penso che un punto interessante qui sia che la stragrande maggioranza delle licenze di software commerciale (e in effetti open source) specificano specificamente che non ci si può fidare del software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Da contratto di licenza Microsoft Word

. Except for the Limited Warranty and to the maximum extent permitted by applicable law, Microsoft and its suppliers provide the Software and support services (if any) AS IS AND WITH ALL FAULTS, and hereby disclaim all other warranties and conditions, whether express, implied or statutory, including, but not limited to, any (if any) implied warranties, duties or conditions of merchantability, of fitness for a particular purpose, of reliability or availability, of accuracy or completeness of responses, of results, of workmanlike effort, of lack of viruses, and of lack of negligence, all with regard to the Software, and the provision of or failure to provide support or other services, information, software, and related content through the Software or otherwise arising out of the use of the Software.

In sostanza, questa frase nella licenza in quasi tutti i software che usi specicamente ti dice che non ti puoi fidare del software e tanto meno che il compilatore è usato.

Il software è come una teoria scientifica, si ritiene che funzioni come specificato fino a quando non lo fa.

    
risposta data 30.12.2015 - 11:24
fonte
2

Come scrittore di compilatori per un linguaggio matematico *, dalla mia esperienza posso dire che in teoria non si può. E alcuni dei bug danno solo risultati errati come (dalla mia lista di vergogna) calcolando 6/3*2 dalla destra 6/(3*2) e emettendo 1 senza crash o dando errori di compilazione senza senso.

Ma IMHO molti compilatori non hanno tanti bug come altri software perché:

  • Scrivere i test delle unità è facile. Ogni affermazione è un'unità e puoi scrivere test semplici come: test_unit("2+(-2)*(-2+1)*3+1",9);
  • Un programma è una combinazione di istruzioni e per ogni programma che genera il risultato corretto ogni singola istruzione deve fornire il risultato corretto (principalmente). Quindi è molto improbabile che ci siano errori mentre il programma fornisce il risultato corretto.
  • Poiché le dimensioni e il numero di programmi scritti aumentano notevolmente le probabilità di cattura degli errori,

Per gli assemblatori, le istruzioni della macchina ecc., anche quanto sopra riportato; d'altra parte la verifica e la validazione nella progettazione e produzione di chip hanno processi molto più rigidi poiché è un enorme business: Automazione della progettazione elettronica .

Prima di andare in produzione ogni CPU dovrebbe essere testata rigorosamente perché ogni bug costa quasi un paio di milioni di dollari: ci sono enormi costi di produzione non ricorrenti nella produzione di chip. Quindi le aziende spendono molti soldi e scrivono un sacco di codice di simulazione per il loro design prima di andare in produzione, anche se questo non fornisce una garanzia al 100% - per esempio: il bug del Pentium FDIV.

In breve è molto improbabile che ci siano errori gravi in compilatori, codici macchina ecc.

La mia umile lingua matematica *

    
risposta data 30.12.2015 - 10:39
fonte
0

Flawless? Loro non sono. Di recente ho installato alcuni "aggiornamenti" e sono passati mesi (e diverse sezioni di codice riprogrammate) in un secondo tempo prima che il mio sito ASP.NET funzionasse di nuovo correttamente, a causa di cambiamenti inspiegabili nel modo in cui le varie cose di base funzionavano o fallivano.

Tuttavia, sono testati e quindi utilizzati da molte persone molto attente ai dettagli, che tendono a notare e segnalare e risolvere la maggior parte delle cose. Stack Exchange è un ottimo esempio (e miglioramento) di come tutte le persone che usano questi strumenti aiutano a testare e analizzare come funzionano questi strumenti incredibilmente complessi e di basso livello, almeno per quanto riguarda l'uso pratico.

Ma impeccabile, no. Sebbene sia possibile vedere le persone su Stack Exchange ottenere informazioni dettagliate sui dettagli delle prestazioni e sulla conformità degli standard e stranezze, ci sono sempre difetti e imperfezioni, specialmente quando persone diverse hanno opinioni diverse su quale sia un difetto.

    
risposta data 30.12.2015 - 07:03
fonte
-1

Per mostrare che i sistemi sottostanti sono impeccabili puoi

a) È necessario dimostrare che sono impeccabili

  1. Prova matematica
  2. Solo realisticamente possibile per programmi banali

b) Esegui un test completo

  1. Possibile solo per programmi banali e alcuni programmi semplici
  2. Non appena un elemento di temporizzazione entra nel test, non è possibile effettuare un test esauriente in quanto il tempo può essere diviso indefinitamente.
  3. Oltre ai programmi banali le possibili opzioni di esecuzione esplodono esponenzialmente.

Nel test del software, il test esaustivo viene utilizzato solo in test di unità di alcune semplici funzioni.

Esempio: Se vuoi testare un input utf-8 di 8 caratteri in un campo, fai la scelta di tagliare l'input a 8 volte la lunghezza massima 6 di utf-8 in byte che dà 8 * 6 = 48 byte per avere effettivamente una quantità finita di possibilità.

Ora potresti pensare di aver solo bisogno di testare i 1.112.064 punti di codice validi di ciascuno degli 8 caratteri, vale a dire. 1,112,064 ^ 8 (diciamo 10 ^ 48) test (che è già improbabile possibile), ma in realtà è necessario testare ogni valore di ciascuno dei 48 byte o 256 ^ 48 che è di circa 10 ^ 120, che è la stessa complessità di < a href="https://en.wikipedia.org/wiki/Shannon_number"> scacchi rispetto al numero totale di atomi dell'universo di circa 10 ^ 80.

Invece puoi usare, in ordine crescente di sforzo e ogni test dovrebbe riguardare tutto il precedente:

a) prova un campione buono e cattivo.

b) copertura del codice, es. prova a testare ogni riga di codice, che è relativamente semplice per la maggior parte del codice. Ora puoi chiederti che cos'è l'ultimo 1% del codice che non puoi testare ... bug, codice morto, eccezioni hardware ecc.

c) copertura del percorso, vengono testati tutti i risultati di tutti i rami in tutte le combinazioni. Ora sai perché il reparto test ti odia quando le tue funzioni contengono più di 10 condizioni. Inoltre ti chiedi perché l'ultimo 1% non può essere testato ... alcuni rami dipendono dai rami precedenti.

d) test dei dati, testare un numero di campioni con valore di frontiera, valori problematici comuni e numeri magici, zero, -1, 1, min +/- 1, max +/- 1, 42, valori rnd. Se questo non ti offre la copertura del percorso sai che non hai catturato tutti i valori nella tua analisi.

Se lo fai già, dovresti essere pronto per l'esame di fondazione ISTQB.

    
risposta data 31.12.2015 - 15:30
fonte

Leggi altre domande sui tag