2012-11-02 10 views
5

Ich versuche, ein Problem zu debuggen, bei dem die falsche Version einer Funktion aufgerufen wird, was zu einem segfault führt. Der Code, den ich kompiliere, wird maschinell erzeugt und enthält eine Funktion namens 'mal', die eine komplexe Multiplikation ihrer zwei Argumente vornimmt. Dieser Code wird vor dem Verknüpfen mit einer übergeordneten Objektdatei in eine .o-Datei kompiliert.C-Programm verweist auf falsche Version der Funktion

Wenn Sie diesen Code segfolds ausführen und gdb zeigt an, dass es in der glibc-Version von 'mal' ist, die nicht einmal die gleiche Anzahl von Argumenten benötigt. Es gibt keine Instanzen von "#einschließen" irgendwo in diesem Code.

Das Ändern des Namens von Zeiten zu Zeiten1 löst das Problem. Dies ist jedoch keine langfristige Lösung, da der Code maschinell generiert wird und der Name dieser Funktion von Zeit zu Zeit unattraktiv ist.

Das ganze Chaos kompiliert Reinigung mit -Wall, also bin ich mir nicht sicher, wo ich suchen soll. Irgendwelche Ideen, wie man das löst?

+3

Es ist nicht üblich, mehrere C-Dateien zu einem einzigen '.o' zu kompilieren. Wenn "times.c" eine von mehreren C-Dateien ist, die in dieser Gruppe kompiliert wurden, könnte dies das Problem erklären. – Gene

+1

Ein '# include' bringt nur Deklarationen mit; Es hat keine Kontrolle über die Verknüpfung. Wenn Sie eine Funktion namens "mal" deklarieren und sie dann aufrufen, erzeugt der Compiler eine Objektdatei, die eine Referenz auf diesen Namen in seiner Symboltabelle enthält, und dann sucht der Linker nach einer Definition dieses Namens, wenn er die endgültige ausführbare Datei erzeugt . Es gibt eine 'mal'-Funktion in libc, und genau das hat der Linker gefunden. – Wyzard

+0

Gene - Könnten Sie Ihren Kommentar näher erläutern? times.c ist in der Tat eine separate C-Datei, die in das einzelne Objekt kompiliert wird. Warum erwarten Sie, dass dies ein Problem verursacht? Es gibt wirklich nur einen Einstiegspunkt, an dem ich mich interessiere. Und 'mal' gehört nicht dazu. d.h. es sollte vollständig intern sein und nicht als dynamisches Symbol für höhere Schichten angesehen werden. Gibt es eine Möglichkeit, gcc darüber zu informieren? –

Antwort

0

Also die wirkliche Antwort auf dieses ist -fno-builtin-times zu gcc zu werfen. Das vermeidet das Problem ordentlich und unkompliziert.

Dies setzt natürlich voraus, dass Sie den Namen times nicht in einen Zustand ändern können, der nicht mit einer von glibc bereitgestellten Funktion in Konflikt steht.

3

C verwendet nur den Namen einer Funktion als Bezeichner, sodass zwei (exportierte) Funktionen mit demselben Namen in Konflikt geraten. Normalerweise werden alle exportierten Namen einer Bibliothek mit einem eindeutigen Präfix vorangestellt. Die andere Alternative besteht darin, C++ als "ein besseres C" zu verwenden und Ihren C-Code einfach mit einem C++ - Compiler zu erstellen, indem Sie C++ - Name-Mangling verwenden.

+0

Sollte in diesem Fall der Linker mit "Duplicate Symbol" nicht würgen? –

+0

Nicht, wenn Sie es zwingen, zwei verschiedene .o-Dateien mit demselben Symbol in sie zu ziehen. – bmargulies

+0

@ H2CO3 UNIX-Linker * nie * beschweren, wenn das gleiche Symbol in der Hauptdatei und in einer gemeinsam genutzten Bibliothek definiert ist ('libc.so.6' hier) - solche Symbol Interpositionierung ist ziemlich häufig und oft sehr nützlich. –

Verwandte Themen