Mam pakiet oprogramowania napisany w "C". Zazwyczaj jest to kompilowane przy użyciu acc i run w systemie UNIX Solaris, ale mam zadanie uruchomienia go pod Linuksem na pudełku x86_64.Błąd segmentacji: 0x0000000000000001 w ??() próbuje skompilować/połączyć pod Linuksem
Nie jestem szczególnie zaznajomiony z gcc lub Linux, ale udało mi się skompilować kod przy minimalnej ilości zmian, aby usunąć ostrzeżenia, których nie było w systemie Solaris. Używam następujące polecenia kompilacji (wywoływana ze skryptu, stąd zmienne środowiskowe):
/usr/bin/gcc -L/tmp/lib -L/tmp/usr/lib -c -fPIC -g -I$WORKING_DIR $INCLUDE $WORKING_DIR/$FILE
Większość źródła jest następnie umieszczany w dzielonych (.so) bibliotek, również poprzez skrypt, za pomocą następującego polecenia:
ld $GLOSS_SUB_DIR/$REL_DIR/obj/$PREFIX*".o" -G -o $GLOSS_SUB_DIR/$REL_DIR/lib/$LIB$NEW_MIN_VER_NO
próbkę makefile dla pliku wykonywalnego o nazwie „gsproc” przedstawia się następująco:
CONTROL_NO = $(shell awk 'BEGIN{FS=","} /control/ {printf "%s%s", $$3,$$4} END{}' $$GLOSS_DIR/subenv_list)
CTRL_PATH = $(GLOSS_DIR)/control/$(CONTROL_NO)
OBJECTS = $(CTRL_PATH)/nolib/gsproc.o \
$(CTRL_PATH)/nolib/w_bkg_shared.o
LIBS = -lcontrolw \
-lsharew \
-lsybdb64
gsproc: $(OBJECTS)
gcc -shared -fPIC -o $(TMP_DIR)/gsproc \
-L $(SYBASE)/$(SYBASE_OCS)/devlib \
$(OBJECTS) $(LIBS) -lm -lc –lnsl
i okazały się skuteczne w kompilacji, a następnie łącząc cały kod wykonywalny, ale każdy teraz przewraca się natychmiast po uruchomieniu z błędem segmentacji i zrzutem rdzenia. Wszystko, co dostaję z gdb, to:
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-50.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /gloss_env/GLSLAZ_TST2/control/C2.0.0/bin/gsproc...done.
(gdb) run
Starting program: /gloss_env/GLSLAZ_TST2/control/C2.0.0/bin/gsproc
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ??()
Nie wygląda więc na to, że problem dotyczy kodu, jako takiego. Prawdopodobnie robię coś nie tak z opcjami kompilatora lub linkera.
Użyj gcc, a nie ld do łączenia. –
Dzięki za opinię. Rozważyłem to, ale myślałem, że gcc po prostu dzwoni do ld? Odziedziczyłem dość złożony zestaw skryptów, które obsługują kompilację i populację bibliotek współdzielonych. W zależności od prefiksu w pliku źródłowym obiekty muszą być umieszczone w różnych bibliotekach, więc starałem się nie wprowadzać zbyt dużych zmian w bieżącym mechanizmie. Jeśli miałbym wypełnić bibliotekę .so przez gcc, jaka jest opcja wiersza poleceń do użycia? Jak mam powiedzieć, do której biblioteki należy załadować obiekt? – user2311565
gcc wywołuje ld, ale z zastosowanymi wewnętrznymi opcjami, których w innym przypadku brakuje, jeśli używasz bezpośrednio ld. Powinieneś prawdopodobnie przeczytać: http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html. Najlepiej byłoby, gdybyś użył do tego rzeczywistego systemu kompilacji, który zapewniłby poprawną kompilację. Polecam CMake (http://www.cmake.org), który pozwala używać tego samego systemu kompilacji na wszystkich platformach. Automake (http://www.gnu.org/software/automake) to kolejna alternatywa, która współpracuje z Autoconf (http://www.gnu.org/software/autoconf). Zasadniczo użyj CMake, jeśli możesz. –