Come hanno fatto il debug degli errori di segmentazione prima della memoria protetta?

20

Ora, quando faccio un errore di programmazione con i puntatori in C, ottengo un bel errore di segmentazione, il mio programma va in crash e il debugger può persino dirmi dove è andato storto.

Come hanno fatto nel momento in cui la protezione della memoria non era disponibile? Riesco a vedere un programmatore DOS perdere tempo e schiantare l'intero sistema operativo quando ha commesso un errore. La virtualizzazione non era disponibile, quindi tutto ciò che poteva fare era riavviare e riprovare. È andato davvero così?

    
posta Bart Friederichs 29.04.2013 - 12:28
fonte

5 risposte

35

I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake.

Sì, è più o meno quello che è successo. Sulla maggior parte dei sistemi che avevano mappe di memoria, la posizione 0 era contrassegnata come non valida, in modo che i puntatori nulli potessero essere facilmente rilevati, perché quello era il caso più comune. Ma c'erano molti altri casi e hanno causato il caos.

A rischio di sembrare un imbecille, dovrei sottolineare che l'attuale attenzione al debug non è la via del passato. Sono stati fatti molti più sforzi per scrivere programmi corretti, piuttosto che rimuovere bug da programmi errati. Alcuni di questi erano perché quello era il nostro obiettivo, ma molto perché gli strumenti rendevano le cose difficili. Prova a scrivere i tuoi programmi su carta o su schede perforate, non in un IDE e senza il vantaggio di un debugger interattivo. Ti dà un assaggio di correttezza.

    
risposta data 29.04.2013 - 13:01
fonte
23

Ai tempi della mia vita, non avevamo la protezione della memoria e tutto il nostro entusiasmante business! Abbiamo usato printf per determinare dove eravamo nel programma, e ci è piaciuto !

Anche se in tutta serietà, di solito significava che eravamo solo più attenti. Dove si chiama malloc, ci doveva essere un free altrove nel programma, e tale controllo era rigoroso perché nel caso di un problema, come hai chiaramente sottolineato, gli errori di segmentazione non sono errori utili.

Nel caso di tali errori, il meglio che si possa fare è cercare di capire quando tali errori di segmentazione si verificano (usando printf) e, guardando il codice, determinare il motivo dell'accesso alla memoria in quel punto non era valido e funziona a ritroso da lì.

In sostanza, oggi accade la stessa cosa, tranne che usiamo i debugger per determinare quando si verificano errori, ma devi ancora capire perché è successo, e non è sempre così semplice come trovare il linea in cui si è verificato l'errore. Gli errori causano errori come una reazione a catena, e se tu fossi un programmatore C in quei giorni, hai passato il 20% del tuo tempo a programmare e il resto del tempo a tirare fuori i tuoi capelli fissando bug.

    
risposta data 29.04.2013 - 12:52
fonte
6

bene ..

un segfault è un indicatore davvero bello che qualcosa non va, ma devi ancora trovare la causa principale. Quindi se fai la domanda come trovi la causa principale della risposta non è molto diversa oggi di quanto non fosse allora. Naturalmente i linguaggi e gli strumenti sono diventati più facili da utilizzare ma il taktik generale è lo stesso:

    La registrazione
  • aiuta a trovare l'area in cui si trova il tuo problema. La ricerca binaria printf è una forma di esso.
  • debugging, passo dopo passo, punti di interruzione e orologi
  • refactoring per comprendere meglio
  • a fissare il codice
  • guarda la memoria / core dump
  • alimentandolo con dati diversi
  • mostrandolo ad altre persone
  • passa a una lingua senza puntatori (e una nuova serie di problemi) ...

A un livello più astratto hai tre approcci: 1. lavora con il codice 2. Guarda il programma mentre è in esecuzione 3. guarda i risultati dopo aver fatto qualcosa di stupido

btw un errore del puntatore non deve creare un segfault.

Come programmatore Amiga ho usato praticamente tutto. E sì si riavvia dove pratica comune.

    
risposta data 29.04.2013 - 12:53
fonte
4

Su IBM 360, eseguendo i lavori batch Fortran, abbiamo utilizzato i dump core esadecimali. Una tale discarica potrebbe essere spessa un centimetro di carta per stampanti in bianco e verde fan-fold. Diceva cosa fossero i registri e da lì potevamo tornare indietro e capire cosa stava facendo il programma. Potremmo trovare ogni subroutine e capire dove ha memorizzato il suo indirizzo di ritorno, in modo da poter vedere il contesto. Sarebbe utile avere un elenco assembler del programma.

    
risposta data 29.04.2013 - 20:17
fonte
2

Una volta stavo lavorando sulla correzione di bug in un famoso software di presentazione di Windows 3.1.

Ho avuto un bug che, quando si è verificato, ha causato la Blue Screen of Death.

L'errore si verificava solo quando un determinato ciclo era stato eseguito più di 1000 volte. Ho usato le funzioni avanzate del debugger per far passare un punto di interruzione 1000 volte e poi ho fatto un attento passaggio nel programma. Ogni volta che sono andato troppo lontano o ho saltato una chiamata di funzione che conteneva il bug Windows Blue Screened.

Infine, dopo diversi giorni di lavoro, l'ho ristretto a una funzione che stava esaurendo la memoria e invece di visualizzare un messaggio di errore, ha aggiunto il messaggio di errore a un buffer. Con ogni iterazione successiva ha distrutto più memoria fino a quando qualcosa di cruciale è stato sovrascritto e Windows è stato cestinato.

Il debug delle competenze e la perseveranza è stata la soluzione.

    
risposta data 02.05.2013 - 13:08
fonte

Leggi altre domande sui tag