Segfault è sempre l'errore del programmatore?

6

Un segfault (indice della matrice fuori limite) è sempre l'errore del programmatore o potrebbe essere un uso improprio da parte dell'utente?

    
posta Niklas Rosencrantz 28.06.2017 - 08:52
fonte

10 risposte

24

A parte una parte della specifica è "In tale circostanza e tale circostanza, si invoca un comportamento indefinito" (C / C ++) o "innescare un IndexOutOfBoundsException ", è sempre colpa del programmatore.

Il compito di un programma è di reagire adeguatamente a tutti gli input, e questo include input errati, incompleti o addirittura sovversivi. In generale, se l'utente fornisce input inutilizzabili, un programma dovrebbe fornire una risposta determinata, come un messaggio di errore o un prompt di ripetizione, e non una reazione definita dall'implementazione dal sistema runtime; tale comportamento di solito non è utile per l'utente e potrebbe causare vulnerabilità alla sicurezza.

    
risposta data 28.06.2017 - 09:03
fonte
17

No, a volte l'hardware viene colpito da un raggio cosmico.

È comune per l'hardware che non ha la correzione dell'errore di capovolgere un singolo bit quando la memoria del semiconduttore viene colpita da una radiazione ad alta energia. Se si tratta di un bit in un contatore di loop o di un registro di indirizzi, si otterrà l'accesso all'indirizzo sbagliato. Il software scritto per applicazioni aerospaziali e il precedente software GPGPU utilizzava in genere sistemi ridondanti e votazioni per allontanarsi da questo, dove l'hardware era troppo costoso.

Questo documento NASA contiene ulteriori informazioni sul software tecniche per mitigare questo fenomeno e puoi sempre guardare in wikipedia per componenti elettronici per l'irradiazione di radiazioni . Questo documento illustra l'effetto della correzione degli errori nella simulazione su una GPU - Non ricordo se la causa principale sia la causa principale di errori nelle prime GPU era la radiazione o altri errori software .

    
risposta data 28.06.2017 - 10:32
fonte
6

Come altri hanno affermato correttamente, è colpa del programmatore, ma dal momento che hai chiesto Java e C, vorrei spiegare le differenze:

In C

Il tuo programma deve impedire che tale situazione si verifichi in tutte le circostanze, ovunque utilizzi gli array. Assicurarsi che le variabili dell'indice non esauriscano i limiti dell'array. Altrimenti ciò si tradurrà in un comportamento indefinito, imprevedibile e forse problemi di sicurezza.

Questo tipo di comportamento imprevedibile dovrebbe rendere evidente il motivo per cui è chiaramente responsabilità del programmatore non permettere che ciò accada.

In Java

È possibile impedire che ciò accada, ma se non lo fai, il programma si comporterà comunque in un modo definito: genererà un'eccezione specifica. Il tuo programma ha quindi la possibilità di cogliere questa eccezione (e nella maggior parte dei casi reali dovrebbe), a qualsiasi livello dello stack di chiamate.

In caso contrario, l'ambiente runtime Java uscirà dal programma più o meno con garbo, con un messaggio di errore tecnico che molto probabilmente non è molto utile dal punto di vista dell'utente. Ci possono essere rari casi in cui questo è un comportamento accettabile. Tuttavia, per la maggior parte dei programmi, come utente, se "l'array fuori limite" è stato causato da qualche parametro di input inatteso, mi aspetterei che il programma mi dicesse che quale parametro di input era probabilmente sbagliato. E ciò non avviene automaticamente. Uno deve implementare questo.

Quindi, affinché il programma non reagisca in modo molto ostile all'utente, è anche responsabilità del programmatore produrre un messaggio di errore più utile.

    
risposta data 28.06.2017 - 12:59
fonte
4

Sì, è sempre colpa di un programmatore. O ha incasinato i calcoli della sua lunghezza o non ha correttamente disinfettato l'input dell'utente.

    
risposta data 28.06.2017 - 08:56
fonte
0

Quasi sempre.

Casi in cui non si tratta dell'errore del programmatore:

  1. quando è intenzionale (ad esempio, come ottenere segfault)
  2. quando si tratta di un malfunzionamento dell'hardware
  3. quando qualcuno sta / sta manomettendo il programma o il suo ambiente (cambiando l'alimentazione, irradiando il computer, modificando i dati in memoria, modificando gli eseguibili (ma è il programma originale? chi è il programmatore))

  4. può essere un uso improprio da parte dell'utente se il contratto specifica che il programmatore non può fatturare ore per gestire input inattesi e che cosa succede È un comportamento indefinito.

risposta data 28.06.2017 - 17:40
fonte
0

could it be misuse from the user?

Sì.

Ci sono innumerevoli modi in cui un utente può abusare di un'applicazione. Alcuni dei quali nessuna applicazione ragionevole può difendersi, ad esempio fornire le librerie sbagliate, caricare un plug-in incompatibile.

    
risposta data 28.06.2017 - 19:41
fonte
0

Is a segfault ... always the programmer's mistake ... ?

No.

Is a segfault ... sometimes the programmer's mistake ... ?

Sì.
Tutti possono commettere errori.

Is a segfault ... sometimes the user's mistake ... ?

Non direttamente.

L'utente farà qualcosa che ritengono valido, ma l'applicazione interpreta erroneamente questo, generando dati che causano l'interruzione del codice dell'applicazione.

Il mio mantra:

Bad Code breaks.  Period.  
Good Code gets broken by Bad Data. 

Se il codice è fondamentalmente sbagliato, verrà sempre interrotto. In tal caso, sapere dove si è verificato l'errore, come previsto dalla maggior parte delle tracce di stack, è tutto ciò che serve per trovare e risolvere il problema.

Se il codice è fondamentalmente corretto ma lo sviluppatore, ad esempio, ha perso un caso limite, il codice sarà ancora interrotto, ma solo sapere dove è non abbastanza da risolverlo. È inoltre necessario conoscere i dati di input che hanno causato la rottura, che StackTraces raramente, se mai fornisce.

    
risposta data 29.06.2017 - 13:39
fonte
0

In generale, se un utente può bloccare un programma semplicemente immettendo dati errati su un prompt (o in una finestra di dialogo), il programmatore è sicuramente in errore. Le persone commettono errori (a volte deliberatamente) e un programmatore che non tiene conto di questo quando implementa il proprio codice è negligente. Questo è particolarmente true in C, poiché non genererà alcun tipo di eccezione IndexOutOfBounds sull'indicizzazione oltre la fine di un array o qualcosa del genere.

Alcuni errori sono fallimenti dell'immaginazione (nessuno modo qualcuno potrebbe digitare più di 128 caratteri per un singolo input), alcuni semplicemente non considerano casi limite (overflow numerico, divisione per zero, ecc. ). Alcuni sono il risultato di interazioni tra diversi pezzi di codice che funzionano bene in isolamento, ma in qualche modo si scontrano reciprocamente. Spesso soffriamo di visione da tunnel quando sviluppiamo il nostro codice (specialmente quando sono frettolosi), quindi non lo esercitiamo adeguatamente con input negativi.

Sfortunatamente, il controllo dell'integrità mentale e la disinfezione in C sono un dolore nel culo . Bulletproofing scanf è spesso un esercizio di futilità, quindi quello che molti di noi fanno è leggere tutto come testo con fgets e quindi analizzare e convertire secondo necessità, il che fa sì che il codice abbia dimensioni variabili (questa risposta mostra quanto ridicolo possa essere ottenuto).

Ora, se un utente sta facendo qualcosa che non è semplicemente inserendo input a un prompt (per esempio, eseguendolo sotto gdb e facendo casino con roba sotto il cofano), allora non è qualcosa di programmatore può necessariamente guardia contro.

    
risposta data 29.06.2017 - 17:05
fonte
0

Questo ovviamente dipende dall'applicazione.

Se vuoi mettere rapidamente insieme un'applicazione che usi solo una volta, non sarebbe saggio aggiungere un controllo approfondito del puntatore. In questo caso, un segfault può semplicemente significare che hai immesso dati non validi nell'applicazione. Ovviamente, potresti voler usare un linguaggio di livello superiore come Python, ma poi di nuovo se le prestazioni sono importanti, Python potrebbe essere troppo lento.

Tuttavia, su un software di qualità produttiva, direi che i segfault non sono accettabili, e quindi, è colpa del programmatore. Immagina per es. un segfault causato da un pacchetto di rete non valido. Ciò potrebbe causare una vulnerabilità in caso di arresto anomalo della tua applicazione.

    
risposta data 29.06.2017 - 21:26
fonte
0

Per C, direi "no". Potrebbe essere un errore utente / client. Ad esempio, non tutte le funzioni che accettano un puntatore devono necessariamente sprecare la manutenibilità del codice e l'efficienza computazionale controllando se il puntatore è null se la funzione è documentata in modo tale che è ovvio che non si debbano passare puntatori nulli o penzolanti ad esso. Ciò potrebbe persino iniziare a oscurare i bug altrove.

Se consideri l'errore delle persone che implementano le funzioni, allora la maggior parte della libreria standard C è rotta e bacata e ha bisogno di una riscrittura epica, dal momento che è possibile segfault molte funzioni nella libreria standard C semplicemente passando loro input non validi (es: qsort oltre la fine di un buffer). Oppure puoi semplicemente dire che chiunque passi i puntatori non validi a funzioni come qsort lo utilizza in modo errato, e questa è una visione molto più pratica.

Non è possibile controllare efficacemente il secondo caso (puntatore pendente) in una funzione. Le funzioni C possono essere indebitamente sfruttate da coloro che usano / chiamano se passano in input non validi per la funzione, quindi ci sono molti casi in cui l'uso improprio di un'interfaccia C potrebbe essere il risultato di "errore utente" in modi che portano a segfault e altri arresti anomali.

Se si desidera scrivere funzioni che rilevano errori e errori del programmatore di quelli che usano l'interfaccia, C è generalmente la lingua sbagliata per il lavoro. In realtà una grande parte del mio interesse per C è che tende a segfault e si arresta in modo spettacolare a seguito di un uso improprio. Preferisco quella ai bachi difficili da rilevare che possono facilmente volare sotto il radar del test.

Ora sto assumendo per "utente", intendi qualcuno che chiama una funzione. Non "utente finale" di un'applicazione, ma "utente" di una funzione o di una libreria. Se stai parlando di utenti finali, il programma non dovrebbe mai bloccarsi a causa di un uso improprio a meno che non siano, ad esempio, sviluppatori di plug-in che scrivono plugin C per la tua API. Il software di produzione non deve presentare, ad esempio, campi di input all'utente in una GUI in cui possono digitare valori troppo grandi e segfault del software. Il software non dovrebbe consentire tale uso improprio.

    
risposta data 10.12.2017 - 15:14
fonte

Leggi altre domande sui tag