Dovrei preoccuparsi di “Salto condizionato o mossa dipende dal valore Non inizializzato (s)”?

StackOverflow https://stackoverflow.com/questions/765913

  •  12-09-2019
  •  | 
  •  

Domanda

Se hai utilizzato MemCheck (da Valgrind) probabilmente sarete familiarità con questo messaggio ...

  

Salto condizionato o mossa dipende dal valore non inizializzato (s)

Ho letto su questo e si verifica solo quando si utilizza un valore non inizializzato.

MyClass s;
s.DoStuff();

Questo funziona perché s viene inizializzato automaticamente ... Quindi, se questo è il caso, e funziona, perché MemCheck dirmi che è inizializzata? Se il messaggio viene ignorato?

Forse ho capito male dove l'errore mi stava dirigendo. Dal manuale Valgrind, il frammento di reale erronea è ...

int main()
{
  int x;
  printf ("x = %d\n", x);
}

Tuttavia, nel mio codice, non riesco a vedere nulla di simile. Ho notato però che la funzione in cima alla pila traccia MemCheck mostra me è una funzione virtuale; questo potrebbe essere qualcosa a che fare con esso?

==14446== Conditional jump or move depends on uninitialised value(s)
==14446==    at 0x414164: vimrid::glut::GlutApplication::FinishRender() (GlutApplication.cpp:120)
==14446==    by 0x422434: vimrid::demos::filterdemos::FilterDemo3::Render() (FilterDemo3.cpp:260)
==14446==    by 0x412D3D: vimrid::VimridApplication::UpdateAndRender() (VimridApplication.cpp:93)
==14446==    by 0x4144BA: vimrid::glut::GlutApplication::glutHandleDisplay() (GlutApplication.cpp:201)
==14446==    by 0x41486A: vimrid::glut::GlutApplication::glutCallbackDisplay() (GlutApplication.cpp:277)
==14446==    by 0x54D9FAA: (within /usr/lib64/libglut.so.3.8.0)
==14446==    by 0x54DDA4A: fgEnumWindows (in /usr/lib64/libglut.so.3.8.0)
==14446==    by 0x54DA4A3: glutMainLoopEvent (in /usr/lib64/libglut.so.3.8.0)
==14446==    by 0x54DAEB5: glutMainLoop (in /usr/lib64/libglut.so.3.8.0)
==14446==    by 0x413FF8: vimrid::glut::GlutApplication::Run() (GlutApplication.cpp:112)
==14446==    by 0x41249D: vimrid::Launcher::runDemo(vimrid::VimridSettings&) (Launcher.cpp:150)
==14446==    by 0x412767: vimrid::Launcher::Launch(int, char**) (Launcher.cpp:62)

Aggiornamento 1:

Ho preso uno sguardo al GlutApplication.cpp: 120, e sembra che la variabile non inizializzata era stata passata a una funzione su quella linea. Semplice!

È stato utile?

Soluzione

Puoi pubblicare un campione più completo? E 'difficile capire come ci sarebbe stato quel particolare errore con qualche forma di goto o di flusso cambiando dichiarazione.

I più comunemente vedo questo errore nel codice come il seguente

MyClass s1;
...
if ( someCondition ) { 
  goto Foo:
}
MyClass s2;
Foo:
cout << s2.GetName();

Questo codice è fondamentalmente errato. Il motivo per cui è che anche se S2 ha un costruttore, non è eseguita se someCondition è vero. La dichiarazione goto salterà sopra l'inizializzazione e l'ultima riga del s2 programma sarà inizializzato ed essenzialmente puntare alla spazzatura.

Modifica

Si consiglia inoltre di controllare questa pagina che fornisce suggerimenti su come decifrare questo particolare errore valgrind

https://computing.llnl.gov/code/memcheck/#deciphering4

Addendum

Un'altra causa comune per questo che ho appena trovato è quando si passa su alcune costanti integer a una funzione variadic, che vengono messa in pila come int, ma quando il chiamato ottiene come anela, hai un problema su macchine a 64-bit.

ero quasi sul punto di rinunciare e basta considerare valgrind essere stupido, allora ho capito che semplicemente il cast di correzioni tempo.

Quindi la mia conclusione è:. Prendere sul serio questi messaggi

Altri suggerimenti

È possibile aggiungere il --track-origins=yes bandiera per Valgrind e vi darà informazioni sulle fonti di dati non inizializzate. Esso viene eseguito più lentamente, ma può essere utile.

Fonte: Valgrind Manuale Utente

Se Valgrind afferma che un valore non viene inizializzato, poi nel 99,5% è in realtà non inizializzato. Normalmente, quando i rapporti del compilatore utilizzano di un valore Non inizializzato (-Wuninitialized nel GCC), si controlla la linea srotola, come valore Non inizializzato può essere dichiarata (e non inizializzato), per esempio 10 livelli di funzione inline "chiamate" (o modello si srotola) più in alto, di rapporto GCC reale. Valgrind fa la stessa cosa, ma in fase di esecuzione . Quindi si dovrebbe verificare tutto il percorso in cui il valore Non inizializzato viaggiato da luogo di essere dichiarato (e non inizializzato), al posto in cui è effettivamente utilizzato. Il percorso può essere ad esempio: cascata di chiamate di funzione, dove ogni funzione passa suoi argomenti (ed eventualmente valore Non inizializzato) alla funzione successiva. Valgrind riporterà in ultima funzione, quando il valore è effettivamente utilizzato.

In genere non si deve ignorare quello che gli stati Valgrind. Valgrind non è un semplice programma di traccia. Esso può essere visto come una macchina virtuale:

  

Valgrind è in sostanza un virtuale   macchina usando just-in-time (JIT)   tecniche di compilazione, tra cui   ricompilazione dinamica. niente da   il programma originale viene mai eseguito   direttamente sul processore host.   Invece, Valgrind prima traduce il   programma in una forma più semplice temporanea   chiamato rappresentazione intermedia   (IR), che è un processore neutrale,   modulo SSA-based. Dopo la conversione,   uno strumento (vedi sotto) è libero di fare   qualunque trasformazioni vorrebbe   sul IR, prima di Valgrind traduce   IR di nuovo in codice macchina e lascia   il processore host eseguirlo. Nonostante   si potrebbe utilizzare traduttore dinamico (che   è, i processori host e di destinazione sono   da diverse architetture), essa   non lo fa. Valgrind ricompila binario   l'esecuzione di codice su host e di destinazione (o   simulato) CPU della stessa   architettura. (Wikipedia)

Sarebbe molto utile se si può inviare più di codice, in particolare dalla parte dove Valgrind pensa l'errore è.

Se questo accade ogni volta che si crea un'istanza della classe, probabilmente dimenticato di inizializzare uno dei membri nel costruttore.

E sì:. Si dovrebbe preoccupare di questo errore, quei ragazzi possono davvero mordere

In macchina 64-bit. Solitamente, int richiede 4 byte di memoria. Ma molto tempo avrà 8 byte in memoria. Così semplicemente fare riferimento un valore int come formato di tempo causerà risultato del tutto errata. Un convertito è necessaria in questa situazione.

L'errore non sembra venire dal codice, ma una libreria che si utilizza.

Valgrind è dotato di una certa soppressione errore predefinito, ma che probabilmente non copre la libreria che si sta utilizzando.

  

Gli strumenti di controllo degli errori rilevare numerosi problemi nelle librerie di base, come ad esempio la libreria GNU C, e le librerie client X11, che vengono pre-installato sul sistema GNU / Linux. Non si può facilmente risolvere questi, ma non si vuole vedere questi errori (e sì, ci sono molti!) Così Valgrind legge un elenco di errori di sopprimere all'avvio. Un file di soppressione di default viene creato dallo script ./configure quando il sistema è costruito.

È possibile creare il proprio che si sa sono irrilevanti al codice.

Vedere la simile domanda SO Perché Valgrind non piace il mio utilizzo di glutCreateWindow?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top