Pagina 1 di 8
[MISTERO] C corruzione della memoria
Inviato: lun 3 dic 2007, 19:02
da lamarozzo
Ho il seguente problema con un programma C.
Ho una variabile che setto all'avvio del programma e non modifico più. Come ho verificato con gdb alla fine del programma questa variabile ha cambiato valore. Penso che ci sia una corruzione della memoria. Ho provato con Valgrind ma non rileva nulla. E' possibile?
C'è un modo con gdb per sapere quando una zona di memoria viene modificata? Almeno avrei un'idea di cosa provoca la corruzione.
Grazie.
Inviato: lun 3 dic 2007, 20:42
da Toni
di solito le cose che pasticciano con le zone di memoria sono i puntatori , concentrati sulla parte di codice dove avvengono operazione su puntatori , magari qualcuno punta dove non dovrebbe
Inviato: lun 3 dic 2007, 21:44
da lamarozzo
Sì, il problema è che il programma è distribuito su più file ed il debugging riga per riga comincia a diventare pesante.
Sostanzialmente quello che succede è che ho una variabile che tiene conto della lunghezza di un array. Verso la fine del programma questa variabile la trovo corrotta e quando accedo all'array mi becco un bel segfault. Il fatto è che conosco la locazione fisica della memoria e mi piacerebbe sapere se c'è un tool (ad esempio qualche comando di gdb) che mi segnala quando quella zona di memoria viene toccata. Insomma una sorta di profiler della memoria.
In questo modo risolvere il problema sarebbe molto più facile.
Inviato: lun 3 dic 2007, 21:53
da V
Inviato: lun 3 dic 2007, 23:28
da lamarozzo
Grazie dei link. Googlando un po' ho visto ha DUMA è l'evoluzione di Electric Fence, così ho provato ad utilizzarlo con il mio programma, ma purtroppo non riusciva a linkarsi al mio programma. Boh!
Alla fine ho risolto in modo poco open source. Ho ricompilato il programma con icc (compilatore intel) che, senza neanche tutti i warning attivati, mi ha segnalato subito il problema: con un indice ho sforato la dimensione di un array.
La cosa che mi ha stupito molto è che Valgrind non s'è accorto del problema. Il compilatore intel resta sempre un gioiellino.
A presto.
Inviato: mar 4 dic 2007, 13:47
da V
Strana cosa.....
Compilando con gcc e passand -Wall ti dice qualcosa?
Inviato: mar 4 dic 2007, 15:05
da lamarozzo
No, non dice nulla. Puoi provare anche tu con il seguente programmino che riassume il guaio che ho avuto io:
Codice: Seleziona tutto
static double R[8];
int main()
{
R[8]=2.;
return 0;
}
La dimensione dell'array e l'indice di accesso sono proprio come li ho scritti, cioè noti a tempo di compilazione, eppure gcc non avverte dell'errore sicuro che si sta commettendo. Il compilatore intel invece avvisa subito con un warning.

Inviato: mar 4 dic 2007, 18:58
da V
Mi sa tanto di bug... o meglio, mi sa che proprio non viene fatto il controllo sugli accessi....
La cosa è comunque assai strana....

Inviato: mar 4 dic 2007, 19:34
da lamarozzo
Sempre con il programmino che ho postato poco sù, anche Valgrind non rileva nulla. Com'è possibile?
Io sto usando gcc 4.1.3 e Valgrind 3.2.3.
Inviato: mar 4 dic 2007, 20:29
da gallows
Il "problema" con Valgrind è che non viene effettuato il bound checking per gli array statici.
gcc (vanilla) quel tipo di warning non credo l'abbia mai dato...
Inviato: mar 4 dic 2007, 20:58
da albatros
gallows ha scritto:gcc (vanilla) quel tipo di warning non credo l'abbia mai dato...
Incuriosito, ho dato una rapidissima e probabilmente disattenta occhiata alla pagina di manuale di gcc e in effetti non dovrebbe avvertire della presenza di questo possibile, banale e diffusissimo errore (di solito un codice del genere non è voluto).
Ho provato anch'io con gcc 4.2.2 con -Wall -Wextra e nulla (ho anche giochicchiato un po' modificando il programmino e ottenendo (ovviamente) diversi segmentation fault quando ho esagerato

).
Inviato: mar 4 dic 2007, 22:26
da lamarozzo
Starò più attento con le variabili statiche, anche se non sarebbe male se il compilatore si potesse accorgere di queste situazioni che, per quanto banali, penso si presentino spesso in programmi un po' più estesi.
Ad esempio il compilatore intel restituisce il seguente messaggio:
Codice: Seleziona tutto
prova.c(5): warning #175: subscript out of range
R[8]=2.;
^
Alcuni miei amici preferiscono il Fortran e si mettono a ridere quando gli racconto che ho perso un pomeriggio per cose come questa!

Inviato: mar 4 dic 2007, 23:45
da ccts2002
lamarozzo ha scritto:Alcuni miei amici preferiscono il Fortran e si mettono a ridere quando gli racconto che ho perso un pomeriggio per cose come questa!

perché il fortran crea le variabili e gli array al volo, vero?
dato che sto un pò ''giocando'' con il fortran, la cosa mi interessa...ma forse è OT...
Inviato: mer 5 dic 2007, 0:02
da lamarozzo
Mi riferivo al fatto che il Fortran effettua un controllo stretto sulle aree di memoria in modo tale che se si ha un array di size 5 e si prova ad accedere all'elemento 6, il programma si blocca segnalando l'errore, cosa che non avviene invece in C, dove l'errore può propagarsi in modo subdolo come è successo a me quando ho aperto questo post.
Il Fortran è un ottimo linguaggio per fare calcoli e infatti il settore del calcolo è l'unico in cui viene ancora usato con profitto. Ad esempio gli array Fortran sono molto potenti e versatili. Esistono moltissime librerie scientifiche scritte in Fortran. Certo però non ci scriverei una GUI

Inviato: mer 5 dic 2007, 15:13
da Mario Vanoni
lamarozzo ha scritto:No, non dice nulla. Puoi provare anche tu con il seguente programmino che riassume il guaio che ho avuto io:
Codice: Seleziona tutto
static double R[8];
int main()
{
R[8]=2.;
return 0;
}
La dimensione dell'array e l'indice di accesso sono proprio come li ho scritti, cioè noti a tempo di compilazione, eppure gcc non avverte dell'errore sicuro che si sta commettendo. Il compilatore intel invece avvisa subito con un warning.
:roll:
In C ed in UNIX/Linux e` mandatorio "You must know what you do!".
Dichiari un'array di 8 elementi,
la numerazione e` 0 ... 7,
R[8] quindi non esiste.
Il compilatore Intel e` stato creato per M$, ovvio che segnali errori idioti,
Mario Vanoni