Debería preocuparme por el "Condicional de salto o movimiento depende no inicializado valor de la(s)"?

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

  •  12-09-2019
  •  | 
  •  

Pregunta

Si usted ha usado Memcheck (de Valgrind) probablemente usted estará familiarizado con este mensaje...

Condicional saltar o mover depende del valor no inicializado(s)

He leído acerca de esto y simplemente se produce cuando se utiliza un valor no inicializado.

MyClass s;
s.DoStuff();

Esto va a funcionar porque s se inicializa automáticamente...Así que si este es el caso, y funciona, ¿por qué Memcheck me dicen que es no?Si el mensaje de ser ignorado?

Tal vez no he entendido donde el error se estaba dirigiendo a mí.Desde el Valgrind manual, el real errónea fragmento es...

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

Sin embargo, en mi código, no veo nada de eso.He notado, sin embargo, que la función en la parte superior de la traza de la pila Memcheck me muestra es una función virtual;podría ser esto algo que ver con él?

==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)

Actualización 1:

Eché un vistazo a GlutApplication.cpp:120, y parece que la variable no inicializada fue que se pasa a una función en esa línea.Simple!

¿Fue útil?

Solución

Se puede publicar una muestra más completa? Es difícil ver cómo habría dicho error con alguna forma de Goto o flujo comunicado cambiante.

Me veo con más frecuencia este error en el código como el siguiente

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

Este código es fundamentalmente errónea. La razón es que a pesar de s2 tiene un constructor, no se ejecuta si somecondition es cierto. La instrucción goto saltará durante la inicialización y en la última línea del programa s2 será sin inicializar y esencialmente apuntar a la basura.

Editar

También es posible que desee comprobar hacia fuera esta página que da consejos sobre cómo descifrar este error en particular valgrind

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

Adición

Otra causa común para este que acabo de descubrir es cuando se pasa sobre algunas constantes enteras a una función variadic, que se puso en la pila como enteros, pero cuando el destinatario de la llamada se pone como anhela, tienes un problema en las máquinas de 64 bits.

Yo estaba casi a punto de darse por vencido y simplemente considerar valgrind ser estúpido, entonces me he dado cuenta de que simplemente se convierte para correcciones largos a él.

Así que mi conclusión es:. Tome este serio mensajes

Otros consejos

Puedes añadir el --track-origins=yes bandera para valgrind y se le dará información sobre las fuentes de datos no inicializados. Se ejecuta más lento, pero puede ser útil.

Fuente: Valgrind Manual del usuario

Si Valgrind establece que un valor no es inicializado, a continuación, en el 99,5% está realmente no inicializado. Normalmente, cuando los informes del compilador uso de un valor no inicializado (-Wuninitialized en GCC), comprueba si hay línea desenrolla, ya que su valor no inicializado puede ser declarada (y no inicializado), por ejemplo de 10 niveles de función en línea "llama" (o plantilla desenrolla) mayor, que informe real GCC. Valgrind hace lo mismo, pero en tiempo de ejecución . Lo que debe comprobar camino conjunto en el que el valor no inicializado viajaba de un lugar de ser declarado (y no inicializado), al lugar donde realmente se utiliza. La ruta puede ser por ejemplo: cascada de llamadas de función, donde cada función pasa sus argumentos (y posiblemente valor no inicializado) a la siguiente función. Valgrind reportará en última función, cuando se utiliza realmente el valor.

En general, no se debe ignorar lo que afirma Valgrind. Valgrind no es un programa de rastreo simple. Puede verse como una máquina virtual:

  

Valgrind es en esencia una virtuales   máquina utilizando just-in-time (JIT)   técnicas de compilación, incluyendo   recompilación dinámica. nada de   el programa original nunca se ejecute   directamente en el procesador host.   En su lugar, Valgrind traduce el primero   programa en una forma temporal, más simple   llamada representación intermedia   (IR), que es un procesador de neutral,   forma SSA-base. Después de la conversión,   una herramienta (véase más adelante) es libre de hacer   lo transformaciones que le gustaría   en el IR, antes de Valgrind traduce   el IR de nuevo en código de máquina y permite   el procesador anfitrión ejecutarlo. Aunque   podría utilizar la traducción dinámica (que   Es decir, los procesadores host y de destino son   de diferentes arquitecturas), se   no lo hace. Valgrind vuelve a compilar binaria   código se ejecute en el host y el destino (o   simulado) CPUs de la misma   arquitectura. (Wikipedia)

Sería muy útil si se puede publicar más código, especialmente de la parte donde valgrind piensa que el error es.

Si esto sucede cada vez que se ejemplariza la clase, es probable que se olvidó de inicializar uno de los miembros en el constructor.

Y sí:. Usted debe preocuparse por este error, los chicos pueden realmente morder

En la máquina de 64 bits. Por lo general, int ocupa 4 bytes en la memoria. Pero mucho se llevará a 8 bytes en la memoria. Así que simplemente se refieren como un valor int formato largo causará resultado totalmente incorrecto. Se necesita un converso en esta situación.

No parece El error que venir de su código, pero una biblioteca que está utilizando.

Valgrind viene con cierta supresión de error por defecto, pero que probablemente no cubre la biblioteca que está utilizando.

  

Las herramientas de comprobación de errores detectan numerosos problemas en las bibliotecas de base, tales como la biblioteca de C de GNU, y las bibliotecas de cliente de X11, que vienen pre-instalados en su sistema GNU / Linux. No se puede arreglar fácilmente estos, pero no desea ver estos errores (y sí, hay muchos!) Así que Valgrind lee una lista de errores para suprimir en el arranque. Un archivo de supresión por defecto es creado por el script ./configure cuando el sistema está construido.

Usted puede crear su propia que sabe que son irrelevantes para su código.

Vea la cuestión de forma parecida ¿Por qué le gusta mi Valgrind el uso de glutCreateWindow?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top