mettre le doigt sur “saut conditionnel ou déplacer dépend de la valeur non initialisée(s)” valgrind message
J'ai donc été faire un mystérieux les valeurs non initialisées message de valgrind et c'est tout le mystère de l'endroit où la mauvaise valeur provient.
Semble que valgrind montre l'endroit où le unitialised valeur finit par être utilisés, mais pas l'origine de la valeur non initialisée.
==11366== Conditional jump or move depends on uninitialised value(s)
==11366== at 0x43CAE4F: __printf_fp (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x43C6563: vfprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x43EAC03: vsnprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x42D475B: (within /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42E2C9B: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42E31B4: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42EE56F: std::ostream& std::ostream::_M_insert<double>(double) (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
==11366== by 0x810B9F1: Snake::Snake::update() (snake.cpp:257)
==11366== by 0x81113C1: SnakeApp::updateState() (snakeapp.cpp:224)
==11366== by 0x8120351: RoenGL::updateState() (roengl.cpp:1180)
==11366== by 0x81E87D9: Roensachs::update() (rs.cpp:321)
Comme on peut le voir, il devient assez cryptique.. surtout parce que quand c'est dit en Classe::MethodX, c'est parfois des points de droit à ostream etc. C'est peut-être en raison de l'optimisation?
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
Juste comme ça. Est-il quelque chose que je suis absent? Quel est le meilleur moyen d'attirer de mauvaises valeurs, sans avoir à recourir à des super-long printf travail de détective?
Mise à jour:
J'ai trouvé ce qui n'allait pas, mais la chose étrange est, valgrind n'a pas indiqué quand la mauvaise valeur a d'abord été utilisé. Il a été utilisé dans une multiplication de la fonction:
movespeed = stat.speedfactor * speedfac * currentbendfactor.val;
Où speedfac était un unitialised flotteur. Cependant, à cette époque, il n'a pas été déclarée et non pas jusqu'à ce que la valeur est à imprimer que j'ai l'erreur.. Est-il un paramètre pour valgrind pour modifier ce comportement?
Vous devez vous connecter pour publier un commentaire.
Utiliser valgrind option
--piste-origine=oui
pour avoir le suivi de l'origine des valeurs non initialisées. Cela va le rendre plus lent, et prendre plus de mémoire, mais peut être très utile si vous avez besoin de retracer l'origine d'une valeur non initialisée.Mise à jour: Concernant le point où la valeur non initialisée est signalé, valgrind manuel unis:
De la Valgrind FAQ:
Ce que cela signifie, c'est que vous essayez d'imprimer/sortie à une valeur qui est au moins partiellement non initialisée. Pouvez-vous réduire vers le bas de sorte que vous savez exactement quelle est la valeur de ce qui est? Après cela, le suivi par l'intermédiaire de votre code pour voir où il est en cours d'initialisation. Les Chances sont, vous verrez qu'il n'est pas complètement initialisé.
Si vous avez besoin de plus d'aide, poster les articles pertinents du code source pourrait permettre à quelqu'un d'offrir plus de conseils.
MODIFIER
Je vois que vous avez trouvé le problème. Notez que valgrind montres pour saut Conditionnel ou déplacer basée sur la non initialisé les variables. Ce que cela signifie, c'est qu'il ne fera que donner un avertissement si l'exécution du programme est modifié en raison de la valeur non initialisée (ie. le programme prend une autre branche dans une instruction if, par exemple). Depuis le réel de l'arithmétique, ne comportent pas d'un saut conditionnel ou déplacer, valgrind ne pas vous avertir de cela. Au lieu de cela, il multiplie les "non initialisé" à la suite de l'instruction qui l'a utilisé.
Il peut sembler contre-intuitif qu'il ne fait pas de vous prévenir tout de suite, mais comme mark4o l'a souligné, il le fait parce que les valeurs non initialisées utilisées pour des C tout le temps (exemples: rembourrage au niveau des structures, la
realloc()
appel, etc.) si ces avertissements ne serait pas très utile à cause d'un faux positif de fréquence.