Derselbe Programmcode mit demselben Compiler führt zu verschiedenen Binaries

8

Ich habe ein Problem mit meinem Code, das einige sehr merkwürdige Symptome hat.

  1. Der Code ist auf meinem Computer mit den folgenden Versionen kompiliert:

    a. GCC-Version: 4.4.2

    b. CMAKE-Verson: 2.8.7

    c. QNX (Betriebssystem) Version: 6.5.0

Und der Code hat einen segfault, während er etwas Speicher freigibt und aus einer Funktion austritt (nicht bei irgendeinem Code, nur beim Verlassen einer Funktion).

Das Seltsame daran ist:

  1. Der Code tut es im Freigabemodus, aber nicht im Debug-Modus:

    a. Der Code ist mit einem Gewinde versehen, was auf eine Wettlaufsituation hinweist.

    b. Ich kann nicht debuggen, indem ich es in den Debug-Modus setze.

  2. Der Code, wenn er auf einem Arbeitscomputer mit den gleichen Versionen von allem kompiliert wird, hat dieses Problem nicht.

    a. Die seltsamen Dinge dabei sind, dass der Code der Arbeitskollegen funktioniert, aber auch, dass die aus der Kompilierung auf seiner Maschine erstellte Binärdatei, die die gleiche ist, etwa 6 MB größer ist.

Jetzt kann ich den Code nicht posten, weil er zu groß ist und auch für die Arbeit. Aber kann mir jemand einen Weg weisen, dies zu beheben?

Da ich QNX verwende, bin ich für meine Debug-Tools eingeschränkt, kann Valgrind nicht verwenden und da es in QNX nicht unterstützt wird, hilft GDB nicht wirklich.

Ich suche jemanden, der ein ähnliches / dasselbe Problem hatte und was die Ursache war und wie sie es behoben hat.

BEARBEITEN:

Sooo ... Ich habe herausgefunden, was es war, aber ich bin immer noch ein bisschen verwirrt darüber, wie es passiert ist.

Der Täter-Code war dies:

%Vor%

wo die Definition für getMinimumBoundingBox ist:

%Vor%

und es gibt einen VectorXd zurück, der immer als VectorXd output(6, 1) initialisiert wird. Also habe ich sofort gedacht, richtig muss es sein, weil der VectorXd nicht initialisiert wird, sondern ändert sich dazu:

%Vor%

Aber das hat nicht funktioniert. In der Tat musste ich es beheben, indem ich die Definition der Funktion änderte:

%Vor%

und der Anruf zu diesem

%Vor%

So, jetzt die neue Frage:

Was zum Teufel? Warum hat die erste Änderung nicht funktioniert, aber die zweite, warum muss ich als Referenz weitergehen? Oh und die große Frage, wie zum Teufel ist das nicht kaputt gegangen, als mein Kollege es kompiliert hat und ich es ausgeführt habe? Es ist ein geradliniger Speicherfehler, sicherlich sollte es nicht darauf ankommen, welcher Computer es kompiliert, zumal der Compiler und all die anderen wichtigen Dinge gleich sind. ??

Danke für Ihre Hilfe, Jungs.

    
Fantastic Mr Fox 16.11.2012, 01:21
quelle

2 Antworten

7
  

... das aus dem Kompilieren auf seiner Maschine erstellte Binary, welches das selbe ist, ist ungefähr 6 MB größer

Es lohnt sich, herauszufinden, was der Unterschied ist (auch wenn es sich nur darum handelt, dass sein Build sich versteckt, während es bei Ihnen einen echten Bug gibt):

  • Überprüfen Sie, ob Sie genau den gleichen Code kompilieren (keine nicht festgeschriebenen lokalen Änderungen, keine zusätzlichen Header im Include-Suchpfad usw.).
    • triple-check durch Hinzufügen eines -E -Schalters zu Ihren gcc-Argumenten in cmake, damit Ihre Dateien mit dem gleichen Include-Pfad wie bei der regulären Kompilierung vorverarbeitet werden; Diff die Pre-Prozessor-Ausgabe
  • Vergleichen Sie die Ausgabe von nm oder objdump oder was auch immer Sie für Ihre zwei verknüpften ausführbaren Dateien haben müssen: Wenn ein System oder eine 3rd-Party-Bibliothek eine andere Version auf einer Box hat, kann es hier erscheinen
  • Vergleiche die Ausgabe von ldd , wenn sie dynamisch verlinkt ist, stelle sicher, dass sie beide die gleichen Bibliotheksversionen erhalten
    • Vergleiche die Bibliotheksversionen, die tatsächlich auch zur Laufzeit erhält, wenn möglich. Hoffentlich können Sie eine der folgenden Aktionen ausführen: pldd ausführen, die .so -Einträge in /proc/pid/map vergleichen, den Prozess unter strace / dtrace / truss ausführen und die Runtime-Linker-Aktivität vergleichen

Wie für den Code ... wenn das nicht funktioniert:

%Vor%

und das tut:

%Vor%

Sie haben vermutlich ein Problem mit dem Zuweisungsoperator. Wenn es eine oberflächliche Kopie erstellt und dynamisch zugewiesener Speicher im Vektor vorhanden ist, erhalten Sie zwei Vektoren, die denselben Zeiger enthalten, und sie werden beide free / delete it.

Beachten Sie, dass der Standardwert, wenn der Operator überhaupt nicht definiert ist, diese flache Kopie ist.

    
Useless 20.11.2012, 10:11
quelle
0

Du hast gesagt, du musst wechseln von:

%Vor%

Was war es vorher?

Wenn es war:

%Vor%

und die Kopierkonstruktoren / Zuweisungsoperatoren wurden nicht korrekt implementiert, was das Problem verursacht haben könnte.

Bitte überprüfen Sie, wie sie beide implementiert sind. Hier sind einige Informationen , die hilfreich sein könnten.

    
serengeor 20.11.2012 09:07
quelle