2012-11-02 8 views
5

Próbuję rozwiązać problem, w którym wywoływana jest niewłaściwa wersja funkcji, powodująca błąd segfault. Kod, który kompiluję, jest generowany maszynowo i zawiera funkcję o nazwie "times", która powoduje złożenie wielu jej dwóch argumentów. Ten kod jest kompilowany do pliku .o zanim zostanie połączony z plikiem obiektu wyższego poziomu.C - linki do nieprawidłowej wersji funkcji

Po uruchomieniu tego kodu, segfaults i gdb wskazują, że jest on w wersji "times" glibc, która nie ma nawet takiej samej liczby argumentów. Nie są to instancje "#include nigdzie w tym kodzie.

Zmiana nazwy czasów na times1 rozwiązuje problem. Nie jest to rozwiązanie długoterminowe, jednak ze względu na maszynową naturę kodu i ręczne edytowanie nazwy tej funkcji przez cały czas jest nieatrakcyjne.

Cały bałagan kompiluje czyszczenie - Ściany, więc nie jestem pewien, gdzie szukać. Wszelkie pomysły, jak rozwiązać ten problem?

Compile chain: 
    gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here) 
    gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB) 
    gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib 
+3

Niekonwencjonalne jest kompilowanie wielu plików C do pojedynczego '.o'. Jeśli 'times.c' jest jednym z kilku plików C skompilowanych w tej grupie, może to wyjaśnić problem. – Gene

+1

"# include" tylko przynosi deklaracje; nie ma kontroli nad łączeniem. Jeśli zadeklarujesz funkcję o nazwie 'times', a następnie wywołasz ją, kompilator wytworzy plik obiektowy zawierający odniesienie do tej nazwy w swojej tablicy symboli, a następnie linker będzie szukał definicji tej nazwy podczas tworzenia końcowego pliku wykonywalnego . W bibliotece libc istnieje funkcja 'times' i to właśnie znalazł linker. – Wyzard

+0

Gene - Czy mógłbyś rozwinąć swój komentarz? times.c jest w rzeczywistości oddzielnym plikiem C, który jest kompilowany do tego pojedynczego obiektu. Dlaczego miałbyś oczekiwać, że to spowoduje problem? Naprawdę jest tylko jeden punkt wejścia, który mnie interesuje. "A" czasy "nie są jednym z nich. tj. powinien być całkowicie wewnętrzny i nie powinien być postrzegany jako symbol dynamiczny dla wyższych warstw. Czy istnieje sposób, aby powiedzieć o tym gcc? –

Odpowiedz

0

Tak więc prawdziwą odpowiedzią na to jest rzucenie -fno-builtin-times do gcc. To pozwala uniknąć problemu bez problemu.

Zakłada się oczywiście, że nie można zmienić nazwy times na coś, co nie jest w konflikcie z podaną funkcją glibc.

3

C używa tylko nazwy funkcji jako identyfikatora, więc każda z dwóch (wyeksportowanych) funkcji o tej samej nazwie będzie powodować konflikt. Normalne approch to przedrostek wszystkich eksportowanych nazw w bibliotece z unikalnym prefiksem. Inną alternatywą jest użycie C++ jako "lepszego C" i po prostu zbuduj swój kod C za pomocą kompilatora C++, korzystając z mangowania nazw C++.

+0

Czy w tym przypadku linker nie powinien się dusić z "duplikatem symbolu"? –

+0

Nie, chyba że zmusisz go do przeciągnięcia w dwóch różnych plikach .o z tym samym symbolem. – bmargulies

+0

@ H2CO3 Łączniki UNIX * nigdy * nie narzekają, gdy ten sam symbol jest zdefiniowany w głównym pliku wykonywalnym i we współdzielonej bibliotece (tutaj "libc.so.6") - takie interpelowanie symboli jest dość powszechne i często bardzo użyteczne. –

Powiązane problemy