|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Errore in Cpp - come lo scovo???
Salve,
sto sviluppando un programma in c++, ma da ieri mi sono bloccato alla ricerca di un errore che non riesco a scovare. Il programma ha uno stream di output su un file all'interno del quale vengono appesi dei risultati ottenuti durante la computazione. Fino a ieri tutto andava bene, poi sono iniziati i problemi; è altamente probabile che si tratti di un errore di memoria: - Come si manifesta l'errore: Lancio il programma, quando è terminato, apro il file in cui vengono scritti i risultati e si vede che la parte iniziale dei dati è stata cancellata e sostituita da quadratini vuoti (sotto linux), sotto windows appaiono come quadrati pieni se apro il file con textpad o come spazi bianchi se lo apro con blocco note. - Quando si manifesta l'errore: Si manifesta in modo molto strano. Supponiamo che il programma mi funzioni. Prendo una funzione di una classe, in cui c'è un costrutto switch, aggiungo un ramo case fittizio in cui non faccio nulla: case(50){ break; } durante l'esecuzione il valore 50 nn è mai quello passato nello switch. Questo basta per corrompere il file. Oppure, in un altra funzione dichiaro delle variabili stringa: std::string a1("aaaaaaaa"); std::string a2("aaaaaaaa"); std::string a3("aaaaaaaa"); std::string a4("aaaaaaaa"); std::string a5("aaaaaaaa"); variabili che non sono utilizzate in alcun modo, ne ci sono altre variabili o campi con lo stesso nome da qualke altra parte; questo basta a corrompere il file. Oppure in un altra funzione di un altra classe dichiaro un ofstream: std::ofstream t1("a.a"); tutto ok se ne dichiaro 2 std::ofstream t1("a.a"); std::ofstream t1("b.b"); file corrotto, anche se i files a.a e b.b non vengono in alcun modo coinvolti nel programma, sono semplicemente delle dichiarazioni che restano inutilizzate. E altri esempi simili; insomma sembra che basti aggiungere istruzioni apparentemente innocue, e che al limite neanche vengono eseguite, come il ramo case fittizio, che si presenta il problema. Ora, quello che vorrei sapere da voi è se sapete suggerirmi dei procedimenti o strumenti per effettuare il debug, visto che non ho mai usato strumenti appositi per il debug, e non so come procedere. Purtroppo non posso postare il codice perke è costituito da molte classi e fa uso anche di una libreria installata sul mio sistema. Il tutto avviene sotto linux. Mi piacerebbe avere suggerimenti per sapere come monitorare il file che viene corrotto, perke quando c'è un bug su una variabile si puo risolvere semplicemente, stampando qua e la la variabile per vederne il valore, qui non so come fare per vedere quand'è che subentra l'errore nello stream e soprattutto qual è l'errore che va a sovrascrivere qualke dato in memoria provocando l'errore, perkè è ovvio che gli esempi che ho descritto sopra non sono la causa dell'errore, ma sono solo esempio che rendono visibile l'errore. Ogni suggeriemnto è benacceto, grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jul 2004
Messaggi: 1578
|
Sei sicuro di aver chiuso il file dopo le scritture?
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Benvenuto nel meraviglioso mondo dei buffer overflow. Potrebbe anche essere un doppio free/doppio delete/puntatore non inizializzato.
Non una bella cosa da debuggare, soprattutto se il programma non è strutturato in maniera molto pulita.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Tutti gli stream usati non sono creati dinamicamente, ma sono campi di una classe, questo vale anche per lo stream principale, per cui il distruttore dovrebbe chiuderlo automaticamente, ma anche chiudendolo esplicitametne la situazione nn cambia. ilsensine, lo so che è un errore di memoria, il fatto è che in tutto il programma uso new solo in un punto per creare un oggetto che passo al costruttore di una classe della libreria che uso, e che si assume l'ownership su quell'oggetto, e provvede a distruggerlo alla fine. Nn ho fatto nessun altro new o delete nei miei files. E' improbabilme che possiate indicarmi l'errore senza vedere il programma, vorrei solo sapere come posso procedere per il debug.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Occorrerebbe vedere una bozza di codice compilabile per riprodurre il problema.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Quote:
Resto in attesa di suggerimenti su come procedere per il debug, gdb (che non ho mai usato), mi puo essere utile? grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Senza impazzire con gdb, puoi usare kdevelop, che ha una ottima interfaccia con gdb. Puoi eseguire il programma passo-passo, cercando l'overflow.
Ti consiglio di compilare la libreria con le opzioni di debug, in modo da poterla seguire nel trace del codice.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Ho installato valgrind per il debug:
http://valgrind.kde.org/ e ho provato a laciare il programma in questa macchina virtuale che controlla tutte le scritture/letture in memoria, ma non mi rileva alcun errore...le mie classi sono state compilate con l'opzione -g (è giusta per il debug?) Comuqnue non ho ricompilato la libreria con l'opzione di debug, ma l'ho usata cosi com'è. Ho anche messo kdevelop; ora per usare gdb dovrei mettere dei break point nel programma e farlo eseguire passo passo controllando il contenuto del file durante il debugging? Che altro potrei fare? Grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Quote:
Ma cosa dovrei fare di preciso? Come faccio a cercare l'overflow??? Ammesso che ci sia una qualke istruzione che va a scrivere in memoria alterando il contenuto di certe variabili, come faccio ad individuare ciò? Dovrei avere un'immagine di tutta la memoria utilizzata dal mio programma e controllarla tutta per ogni singola istruzione eseguita...ma come posso realizzare una cosa del genere? Qualcuno puo avere qualke idea poi del perke l'errore non dà mai segmentation fault, ma si manifesta sempre alterando il contenuto del file; in particolare avviene che dino ad un certo punto il file è ok, si esegue un'istruzione che appende del testo al file e come effetto si ottiene che il testo viene appeso alla fine, ma allo stesso tempo una porzione del testo iniziale viene sostituita da quadratini...help.... Grazie e ciao
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Per isolare il problema, innanzitutto comincia a "togliere pezzi" al programma, in modo da debuggarlo con più semplicità. Senza codice sorgente non è facile aiutarti (e anche se lo puoi distribuire, immagino che non si tratti proprio di "un paio di righe di codice"...) Altro suggerimento che ti do: ricompila il programma (e la libreria che usa!) senza _nessuna_ ottimizzazione, e verifica se produce gli stessi errori.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
|
#11 | ||
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Quote:
Quote:
Comuqnue vedo se posso ricompilare o magari aggiungere direttamente i file sorgenti della libreria al mio progetto e linkarla staticamente al mio programma. Grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
||
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Aggiornamento:
ho ricompilato la libreria come indicato da ilsensine, senza ottimizzazione, ma l'errore si manifesta ancora. Ho fatto altre 2 prove: 1 - inserendo i files della libreria nel mio progetto; 2 - ho portato tutto il progetto su windows, nella versione che comprende i files della libreria. Ho poi creato due versioni del codice codice1, codice2. Questo è quello che accade: Dinamca = libreira installata e caricata dinamicamente Statica = libreria compilata col mio programma StaticaWin = libreria compilata nel mio programma, sotto windows Codice:
--------------- Dinamca -------- Statica ------- StaticaWin codice1 Errore OK OK codice2 Errore Errore OK Come al solito dò queste informazioni non perche spero che qulkuno mi dica dove sbaglio, ma perche magari chi è piu esperto di me puo avere dei suggerimenti da fare, o capire che tipo di errore ci sia o suggerire altre prove. Grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Il fatto che senza ottimizzazioni riproduci lo stesso errore, sembrerebbe escludere una gestione scorretta della memoria. Inoltre, se anche su win riesci, in determinati casi, a riprodurre lo stesso errore, rafforza questa idea.
Sono un pò confuso, sinceramente. Ammesso anche che si tratti di un bug nella libreria, non si capisce perché con la versione statica funziona (sotto linux), ma con quella dinamica no... Almeno ora hai delle versioni che sembrano funzionare...
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Su win non sono ancora riuscito a riprodurre l'errore, nonostante utilizzi gli stessi sorgenti che uso sotto linux con il compilatore mingw, ma farò altre prove.
Sotto linux l'errore si presenta sia con la versione statica che con quella dinamica, anche se ho fatto un esempio in cui si presenta solo con la dinamica D'altro canto il fatto che lo stesso sorgente funziona sotto win ma non sotto linux non dovrebbe escludere un errore funzionale del programma?
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals Ultima modifica di anx721 : 28-10-2004 alle 12:11. |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
Ho fatto un'altra prova (che forse avrei dovuto fare dall'inizio); finora ho lavorato con linux installato in una macchina virtuale (VMWare), cosi avevo windows attivo, e dentro vmware avevo linux (madrake 10). Comuqnue, ho provato ad eseguire il programma direttamente da linux e non ho il problema nè nella versione linkata dinamicamente con la libreria, nè con quella statica. Sotto vmware eseguivo il programma su una partizione fat32 montata nel filesystem: questo probabilmente è il problema, perchè dopo le prove positive ottenute eseguendo direttamnte sotto linux, ho provato ad eseguire il programma sempre dentro vmware ma non nella partizione fat32, e là ha funzionato.
Spero che il problema sia effettivametne questo; ho anche eseguito il debug passo passo impostando nell'ofstream come buffer un mio array di caratteri, in modo da poterne controllare il contenuto durante tutta l'esecuzione, e il contenuto era sempre esatto, ma quando eseguivo il flush comparivano i quadratini. Mi piacerebbe tuttavia avere qualke altra conferma del funzionamento del programma. per questo l'ho messo in rete a questo indirizzo: http://xoomer.virgilio.it/world721/tests/tests.zip Se qualcuno vuole fare una prova, basta scompattare ed eseguire il file tests ./tests sarà creato un file tests.txt che, se tutto è andato bene, dovra essere uguale a tests_corretto.txt; se invece vi trovate caratteri strani o le prime righe mancanti significa che qlkosa nn va. Grazie (soprattutto al sensine), e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Domanda/dubbio: la partizione "fat32" montata da linux dentro vmware, era anche montata/utilizzata dal windows reale? Se la risposta è "sì", fai uno scandisk accendendo qualche cero. Hai sicuramente corrotto qualcosa nel file system.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Oct 2002
Città: Roma
Messaggi: 1502
|
La partizione era montata dentro windows (xp). Comuqnue ho eseguito lo scandisk di windows e non mi rileva errori, neanche il comando chkdsk eseguito dentro l'unita mi rileva nulla. Se avvio linux che ho instalato sempre nel mio pc, quindi non dentro vmware, se eseguo il programma sempre in quella partizione non ho il problema. ilsensine, hai provato per caso ad eseguire il mio programma e controllato che non ti dia errori?
Grazie e ciao.
__________________
Sun Certified Java Programmer EUCIP Core Level Certified European Certification of Informatics Professionals |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:46.



















