====== Esercitazione 1 ====== Dove riprendiamo il C sequenziale ed rispolveriamo alcuni strumenti utili quali //debugger preprocessori compilatori linker//. Inoltre introduciamo ''doxygen, valgrind e mtrace'' che ci aiuteranno a scrivere del cdice C piu' ragionevole. ===== Esercizio -1: sul debugging ===== Usare il debugger ''gdb'' o ''ddd'' per trovare cosa non va nei seguenti {{lcs:lcs07:esercitazioni:ese-debug.tar|programmi}} - //ese-gdb1.c// e' una soluzione completa (non funzionante) dell'esercizio percolation (vedi [[lcs:lcs07:esercitazioni:esercitazione1]] dello scorso anno) - //ese-gdb2.c// e' una soluzione parziale (non funzionante) dello stesso esercizio. In particolare si affronta soltanto l'allocazione e l'inizializzazione della matrice ===== Esercizio 0: Getting started -- Preprocessing, compilazione e linking ===== 0.1) Compilare ed eseguire il seguente programma: #include #include int main (void) { double x=3.0; printf("Radice = %f\n",sqrt(x)); return 0; } salvato nel file //ff.c// con gcc -Wall -pedantic ff.c Chi segnala un errore? E' fallita la fase di preprocessing, la compilazione o il linking? Cosa contine il modulo oggetto se specifico l'opzione -c? Come si risolve il problema? 0.2) Cosa accade se eliminiamo la linea #include ? A questo punto cosa va storto? Sapete interpretare i messaggi a video e stabilire chi li ha scritti e perche'? Viene generato l'eseguibile? 0.3) Generare il modulo oggetto con gcc -Wall -pedantic -c ff.c Utilizzare //objdump, nm, readelf// per capire cosa contengono la tabella di rilocazione, la tabella dei simboli esportati ed esterni, le sezioni data, BSS e codice. (utilizzare il man e cercare su google). 0.4) Usare l'opzione //-E// e la //-S// del gcc: che cosa succede? Cosa accade specificando il flag -g assieme a -S? ===== Esercizio 1. Conversioni di permessi ZTL ===== In questo esercizio si richiede di realizzare alcune funzioni che permettono di rappresentare i permessi di una ipotetica ZTL. I permessi sono rappresentati con le seguenti struct typedef struct { /** inizio intervallo di tempo */ time_t inizio; /** fine intervallo di tempo */ time_t fine; } intervallo_t; #define LTARGA 7 /** rappresentazione di un permesso ZTL come coppia targa intervallo */ typedef struct { /** targa veicolo */ char targa[LTARGA + 1]; /** intervallo di tempo permesso*/ intervallo_t in; } permesso_t; la prima rappresenta un intervallo temporale, la seconda un permesso. Un permesso puo' anche essere serializzato come una stringa di formato: XXXXXXX gg/mm/aaaa-hh:nn gg/mm/aaaa-hh:nn dove la targa ''XXXXXX'' e' formata da lettere maiuscole e numeri mentre gli estremi sono rappresentati da giorno (''gg''), mese (''mm''), anno (''aaaa'') ore (''hh'') e minuti (''nn''). Notare che le tre stringhe sono separate da un singolo spazio. Si chiede di realizzare alcuni funzioni di conversione da struct a stringa e viceversa. Nel tar-file {{:lcs:lcs09:esercitazioni:ese1.tar|}} potete trovare il file ''intervals.h'' con le definizioni delle strutture dati e dei prototipi delle funzioni richieste. I commenti all'interno del file sono in fomato doxygen. Sempre nel tar e' presente il file ''Doxyfile'' che pilota la generazione della documentazione fomato HTML. Per generarla basta invocare bash$ doxygen e poi visualizzare il file ''../html/index.html'' con un browser. ===== Esercizio 2. Conversioni ZTL analizzate ===== Utilizzare la funzione ''mtrace()'' e l'utility ''mtrace'' per verificare i leak di memoria nel programma sviluppato nell'esercizio 1. Utilizzare l'utility valgrind per controllare la mancata inizializazzione di variabili, le scritture/letture in aree non allocate, i leak di memoria e altro. Ad esempio: $ valgrind --show-reachable=yes --leak-check=full --leak-resolution=high -v ./exe params dove (''exe params'' e' il nome del vostro eseguibile di test con gli eventuali parametri) e analizzare le risposte.