Asserzioni, errori e arresti anomali: qual è la differenza?

0
49
Shutterstock/SkillUp

Problemi informatici. Tutti prima o poi li abbiamo. Conoscere i dettagli di errori, asserzioni, arresti anomali e altro è fondamentale per comprendere meglio il problema in questione. Scopri tutto al riguardo.

Che cos'è un asser?

Quando uno sviluppatore inizia a scrivere codice, presto introdurranno se dichiarazioni in esso. Un'istruzione if viene utilizzata ogni volta che è necessario testare una determinata condizione. Ad esempio, si potrebbe scrivere un'istruzione if pseudo-codice come segue:

if (water_level > high_water_mark) then { raise_alert }

In altre parole, se il livello dell'acqua supera il limite massimo, viene generato un avviso. Ma forse il sensore dell'acqua è rotto, quindi aggiorniamo il codice in modo che corrisponda:

if (sensor_readout == nonsenso) then { raise_error fail }else{ if (water_level > high_water_mark) then { raise_alert } }

Ottimo, ora avremo un errore e falliremo la routine se sensor_readout non ha senso. E solo se il valore si rivela sensato (a causa della clausola else—cioè, cosa fare nella situazione opposta), procedere con il controllo del livello dell'acqua rispetto all'high_water_mark.

Tuttavia, forse qualcuno ha spento il sensore. Possiamo continuare così per un po'. Possiamo coprire ogni possibile scenario immaginabile e mancarne ancora alcuni. Certo, potremmo coprire ogni possibile situazione con una clausola else matching e verificare che ogni condizione sia confrontata con un'altra, ma anche in questi casi, potremmo aver perso alcune combinazioni di variabili.

Anche se avessimo solo un insieme limitato di variabili con cui lavorare, il numero di possibili combinazioni in cui un pacchetto software può trovarsi è piuttosto numeroso. E per di più, questo tipo di test condizionali avviene abbastanza regolarmente in quasi tutti i software.

Ragionando un po' oltre su questo dilemma, capiamo subito che noi (come sviluppatori) potremmo (proprio come tutti gli esseri umani commettono errori) prima o poi introdurre un codice che consenta al software di entrare in un territorio indefinito. La variabile x è impostata su un valore specifico, la variabile y è assegnata a un'altra, e il codice non lo prevedeva.

Questa è precisamente la situazione che un'asserzione può, in una certa misura, fornire . Un'asserzione è un'altra condizione (Pensaci come un'altra istruzione if.) che asserisce se esiste una data situazione dispari/non comune/non pianificata/non prevista e di solito gestisce tale situazione arrestando il programma piuttosto che continuare a funzionare con uno stato indefinito/sconosciuto .

Mentre la rete che l'asset test getterà è ancora limitata all'intelligenza e alle capacità dello sviluppatore che implementa l'asserzione, un'asserzione può spesso essere fatta più ampia dei confini limitati di if dichiarazioni che testano lo stato di varie variabili, o potrebbe essere reso abbastanza specifico per evitare certe situazioni pericolose.

Ad esempio, supponiamo che il nostro piccolo sensore dell'acqua sia montato in un serbatoio per la pioggia. L'acqua, quindi, non dovrebbe mai bollire. Se il nostro sensore dell'acqua avesse un misuratore di temperatura, tuttavia, potremmo essere sicuri, anche se non dovrebbe mai accadere. Aggiungiamo un'asserzione allo pseudo-codice che abbiamo iniziato sopra.

Invece del punto di ebollizione (100 gradi Celsius), controlleremo un massimo più ragionevole di 70 gradi Celsius, che dovrebbe ancora mai raggiunto quando si pensa di catturare l'acqua piovana, almeno secondo noi. Ricorda la parola “opinione,” poiché questo diventa importante quando si considera l'intelligenza dello sviluppatore che implementa l'asserzione. (Ulteriori informazioni di seguito.)

if (sensor_readout == nonsensical) then { raise_error fail }else{ assert (water_temp < 70.0){ raise_assert_message fail exit } if (water_level > high_water_mark) then { raise_alert } }

Abbiamo scritto l'asserzione al contrario. Il codice deve affermare che la temperatura dell'acqua è inferiore a 70 gradi Celsius. Se non lo è, eseguirà il blocco di codice, che genererà un messaggio di asserzione, quindi il software fallirà e uscirà.

Le asserzioni nel codice effettivo sono abbastanza simili all'esempio sopra. Verificano se una determinata situazione si applica o meno e successivamente arrestano (o bloccano in modo controllato) il programma/software a portata di mano.

Spesso, queste risorse vengono registrate nei file di registro dell'applicazione o anche direttamente sull'output dello schermo. Rivederli e/o cercare una copia dell'esatto messaggio di asserzione nel tuo motore di ricerca preferito spesso (se il bug è stato trovato in precedenza) ti porterà a una segnalazione di bug sullo stesso.

I messaggi di asserzione sono spesso bug, anche se potrebbero essere semplicemente bug nel ragionamento dello sviluppatore. Dopotutto, chi dice che tra 1.000 anni la pioggia potrebbe non essere più calda di 70 gradi Celsius? (Speriamo di no, però!)

Un messaggio di asserzione è l'output reso dall'asserzione introdotta dagli sviluppatori nel codice, cioè l'effettivo output testuale generato dal software e come visualizzato sullo schermo o nei registri. Ad esempio, immagina che questo messaggio di asserzione venga mostrato per il programma sopra.

Assert: (water_temp < 70): (88 < 70): false

Anche se sembra un po' criptico (come lo sono alcuni messaggi assert), guardando un po' più da vicino ci rendiamo conto che nella seconda parte, water_temp è stato scambiato da 88 e che l'output è falso (ovvero, l'asserzione water_temp < 70 non è riuscita poiché l'acqua era di 88 gradi e quindi l'asserzione ha attivato il messaggio di asserzione). Sì, può creare un po' di confusione.

Armati di queste nuove abilità, il debug di un messaggio di asserzione la prossima volta che ne vedi uno diventa molto più semplice. Potresti anche trovare più facile capire esattamente cosa stava andando storto al momento dell'interruzione dell'applicazione.

Che cos'è un errore?

Gli errori di elaborazione si verificano continuamente e per un'ampia varietà di motivi. Accadono sia a livello di sviluppatore che di utente e in ogni fase intermedia. Ad esempio, un tecnico DevOps potrebbe dimenticare di includere un file necessario o un firmatario del pacchetto potrebbe utilizzare la chiave sbagliata per firmare il software e così via.

In breve, un errore del computer può essere definito come un problema con l'hardware o il software del computer. Ci sono alcuni esempi di errore anche nello pseudo-codice limitato sopra. Quando viene soddisfatta la condizione sensor_readout == senza senso, viene visualizzato un messaggio di errore.

Ci sono alcuni errori più comuni di altri. Ad esempio, l'utilizzo di un percorso o un nome file errato è un errore comune. Anche i problemi di alimentazione (ad esempio, batteria scarica) sono errori abbastanza comuni.

Gli errori sono abbastanza separati e diversi dai messaggi di asserzione, anche se il messaggio di asserzione in sé può essere visto come un errore, o meglio, come una situazione indefinita ora coperta dall'asserzione. In generale, un errore del computer di solito si traduce in “Ho bisogno di un essere umano per risolvere questo problema” abbastanza bene.

Man mano che i computer diventano più intelligenti e l'intelligenza artificiale si evolve, si spera che verranno prodotti meno errori, anche se rimane molto spazio per la discussione e persino le discussioni in quell'area.

Cos'è un crash?

Un crash del computer può assumere molte forme. Conosciamo tutti le schermate blu di Microsoft Windows, che tendevano a verificarsi quando un'applicazione si comportava in modo anomalo o si guastava una parte fondamentale del sistema operativo o l'hardware della macchina.

La maggior parte delle volte, tuttavia, un arresto anomalo è un'applicazione software che si è imbattuta in una situazione indefinita. Ci sono molti di questi scenari indefiniti possibili. Un computer potrebbe aver provato a scrivere su un'area RAM già in uso, sconvolgendo se stesso o un'altra applicazione, o forse si è imbattuto in uno scenario in cui ha cercato di dividere per zero (cosa impossibile), o in una situazione simile.

Molti sistemi operativi scrivono un file core dump (se configurato), che consente a uno sviluppatore e, a volte, a un utente finale abbastanza esperto, di eseguire il debug del problema in questione.

Se desideri saperne di più sul debug quando le cose vanno male, inclusa l'analisi dei file di dump del core, probabilmente troverai interessante il nostro articolo Debug con GDB: Guida introduttiva.

Un arresto anomalo potrebbe anche essere il risultato di un'applicazione che si trova in una situazione indefinita, che non viene gestita da un errore (il modo più leggero per un'applicazione di informarti che qualcosa non va) o un'asserzione (un problema più profondo, originariamente escluso dallo sviluppatore come impossibile ma che si verifica ancora ).

Inoltre, tieni presente che un programma compilato per il test—cioè, con informazioni di debug (incluse asserzioni solo a livello di debug) incorporate nel file binario del risultato finale—potrebbe bloccarsi quando produce un assert, come nel caso, ad esempio, del server MySQL.

Conclusioni

In questo articolo abbiamo esplorato le concetti di asserzioni, errori e arresti anomali e come si relazionano. Abbiamo esaminato in modo approfondito come potrebbe apparire l'asserzione all'interno del codice e come si collega a un esempio reale di monitoraggio del livello e della temperatura dell'acqua con un sensore dell'acqua. La prossima volta che ti imbatti in un messaggio di asserzione, dai un'occhiata più da vicino e divertiti con il debug!