Muss ich mir Sorgen über „Bedingter Sprung oder bewegen, hängt von uninitialised Wert (e)“?

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

  •  12-09-2019
  •  | 
  •  

Frage

Wenn Sie Memcheck verwendet haben (von Valgrind) Sie werden wahrscheinlich mit dieser Nachricht vertraut sein ...

  

Bedingter Sprung oder bewegen, hängt von nicht initialisierten Wert (e)

Ich habe darüber gelesen und es tritt nur, wenn Sie einen nicht initialisierte Wert verwenden.

MyClass s;
s.DoStuff();

Dies funktioniert, weil s automatisch initialisiert wird ... Also, wenn dies der Fall ist, und es funktioniert, warum Memcheck mir nicht sagen, dass es nicht initialisiert ist? Sollte die Meldung ignoriert werden?

Vielleicht falsch verstand ich, wo der Fehler mich zu lenken. Von dem Valgrind Handbuch, ist der tatsächliche fehlerhafte Schnipsel ist ...

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

Doch in meinem Code, ich kann nicht so etwas sehen. Ich habe jedoch festgestellt, dass die Funktion an der Spitze des Stapels verfolgt Memcheck zeigt ich eine virtuelle Funktion ist; dies könnte etwas damit zu tun?

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

Update 1:

Ich habe einen Blick auf GlutApplication.cpp: 120, und es sieht aus wie die nicht initialisierte Variable auf dieser Linie um eine Funktion übergeben wurde. Einfach!

War es hilfreich?

Lösung

Können Sie eine umfangreichere Probe abgeben? Es ist schwer zu sehen, wie es, dass bestimmte Fehler mit aus irgendeiner Form von goto würde oder Anweisung fließen zu verändern.

ich am häufigsten sehen diesen Fehler im Code wie folgt aus

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

Dieser Code ist grundsätzlich falsch. Der Grund dafür ist, dass, obwohl s2 einen Konstruktor hat, wird es nicht ausgeführt, wenn someCondition wahr ist. Die goto-Anweisung wird über die Initialisierung springen und in der letzten Zeile des Programms s2 wird nicht initialisiert werden und weisen im Wesentlichen auf Müll.

Bearbeiten

Sie können diese Seite auch prüfen wollen, die Hinweise auf gibt, wie diese besondere valgrind Fehler zu entziffern

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

Nachtrag

Eine weitere häufige Ursache für diese Ich habe nur gefunden, wenn Sie einige Integer-Konstanten über zu einer variadische Funktion, die als ints auf den Stapel gelegt werden, aber wenn der Angerufene als longs bekommt, haben Sie ein Problem auf 64-Bit-Maschinen.

Ich war fast schon aufgeben und betrachten nur valgrind dumm, dann habe ich erkannt, dass es einfach zu lange Behebungen Gießen es.

Also mein Fazit ist:. Nimmt diese Meldungen ernst

Andere Tipps

Sie können die Flagge --track-origins=yes in der valgrind und es werden Ihnen Informationen über die Quellen der uninitialised Daten. Es läuft langsamer, kann aber hilfreich sein.

Quelle: Valgrind Benutzerhandbuch

Wenn Valgrind besagt, dass ein Wert nicht initialisiert wird, dann in 99,5% ist es wirklich nicht initialisiert. Normalerweise, wenn Compiler Berichte eines uninitialised Wert verwenden (-Wuninitialized in GCC), können Sie für die Inline-Check entrollt, als uninitialised Wert kann (und nicht initialisiert) deklariert werden beispielsweise 10 Stufen von Inline-Funktion „Anrufe“ (oder eine Vorlage entrollt) höher als die tatsächliche GCC Bericht. Valgrind macht das gleiche, aber in Laufzeit . Sie sollte also ganzen Pfad überprüfen, in der uninitialised Wert von Ort der erklärt wird (und nicht initialisiert), an die Stelle, wo es tatsächlich verwendet wird. Der Pfad kann beispielsweise sein: Kaskade von Funktionsaufrufen, wobei jede Funktion ihre Argumente gibt (und möglicherweise uninitialised-Wert) zur nächsten Funktion. Valgrind in letzter Funktion berichten, wenn der Wert tatsächlich verwendet wird.

Generell sollte man nicht, was Valgrind Staaten ignorieren. Valgrind ist kein einfaches Trace-Programm. Es kann als eine virtuelle Maschine zu sehen:

  

Valgrind ist im Wesentlichen eine virtuelle   Maschine mit Just-in-Time (JIT)   Kompilierungstechniken, einschließlich   dynamische Neukompilierung. nichts von   das ursprüngliche Programm jemals wird ausgeführt   direkt auf dem Host-Prozessor.   Stattdessen übersetzt Valgrind zuerst die   Programm in eine temporäre, einfachere Form   Intermediate Representation genannt   (IR), die ein Prozessor-neutral ist,   SSA-basierte Form. Nach der Konvertierung   ein Werkzeug (siehe unten) ist frei zu tun,   was Transformationen würde es mögen   auf der IR, bevor Valgrind übersetzt   die IR zurück in den Maschinencode und lässt   der Host-Prozessor ausführen. Obwohl   es könnte die dynamische Übersetzung verwenden (das   die Host und Zielprozessoren ist, werden   , Es aus verschiedenen Architekturen)   nicht. Valgrind neu kompiliert binäre   Code auszuführen auf dem Host und Ziel (oder   simuliert) CPUs der gleichen   die Architektur. (Wikipedia)

Es wäre sehr hilfreich, wenn Sie mehr Code schreiben können, vor allem aus dem Teil, wo valgrind den Fehler denkt, ist.

Wenn dies passiert jedes Mal die Klasse instanziiert, vergessen Sie wahrscheinlich eines der Mitglieder im Konstruktor zu initialisieren.

Und ja:. Sie sollten diesen Fehler sorgen, können die Jungs wirklich beißen

In 64-Bit-Maschine. Normalerweise int dauert 4 Byte im Speicher. Aber lange wird 8 Bytes im Speicher nehmen. So einfach einen int-Wert beziehen, so lange Format völlig falsches Ergebnis führen wird. Ein Konvertit ist in dieser Situation erforderlich ist.

Der Fehler scheint nicht aus dem Code zu kommen, aber eine Bibliothek Sie verwenden.

Valgrind kommt mit einiger Standardfehlerunterdrückung, aber das wahrscheinlich gilt nicht für die Bibliothek, die Sie verwenden.

  

Die Fehlerprüfung Tools erkennen zahlreiche Probleme in den Basisbibliotheken, wie die GNU-C-Bibliothek und die X11-Client-Bibliotheken, die auf Ihrem GNU / Linux-System vorinstalliert. Sie können diese nicht leicht beheben, aber Sie wollen nicht, diese Fehler sehen (und ja, es gibt viele!) So Valgrind liest eine Liste der Fehler beim Start zu unterdrücken. Eine Standard-Unterdrückung Datei wird vom ./configure-Script erstellt, wenn das System aufgebaut wird.

Sie können Ihre eigenen Fehler Unterdrückungen erstellen dass Sie wissen, um Ihren Code nicht relevant sind.

Sehen Sie die ähnliche Frage SO Warum Valgrind nicht mein mögen Verwendung von glutCreateWindow?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top