Два обновления — смотрите в конце этого поста:
После двух бессонных ночей я решила (впервые) напрямую обратиться за вашей поддержкой.
проблема:
Когда я пытаюсь выполнить кросс-компиляцию для Raspberry (RPI) кода в моем Ubuntu Intel, это приводит к коду, который заканчивается на ошибка времени сегментации, когда я запускаю его на RPI
Тот же код, скомпилированный непосредственно в целевой RPI, работает просто отлично. Исходный код становится слишком большим, чтобы ждать его компиляции на RPI, поэтому я хотел ускорить компиляцию на моем Ubuntu.
Решение
1) следуйте инструкциям http://elinux.org/RPi_Kernel_Compilation
2) Скопируйте «rootfs» из моего целевого RPI, включая / lib / usr / opt
3) изменить исходный Makefile проекта так, чтобы он указывал на целевые библиотеки и включал
4) наслаждайтесь быстрой компиляцией
Результаты:
Не удалось на 4-й точке.
Я могу скомпилировать работающее ядро, модули и тривиальное приложение Hello World
Я могу скомпилировать свой проект и запустить его на RPI — он запускается, но всегда терпит неудачу через некоторое время с сегментацией
неисправность. Очень вероятно после первого использования alsa lib.
замечания:
Я использую в своем проекте две внешние библиотеки -> -lasound -lconfig ++ -lconfig и несколько собственных классов в отдельных файлах.
Это мой стандартный Makefile, который выдает рабочий код на RPI
CCC=g++
CXX=g++
RM=rm -f
WARNINGS=-W -Wall -Waggregate-return \
-Wcast-align -Wcast-qual -Wshadow \
-Wwrite-strings -Wno-unused-variable -Wno-unused-parameter
CPPFLAGS=-c -Wall -O3 -DFIXED_POINT=16 -DDEBUG=1 $(WARNINGS) -DREAL_FASTFIR -DFAST_FILT_UTIL
CFLAGS=-c
LDFLAGS=-g -Wall
LDLIBS=-lasound -lconfig++ -lconfig -lc -lm
SRCS=spectrum.cpp kiss_fft.c kiss_fftr.c oled.cpp mibridge.cpp
//OBJS=$(subst .c,.o,$(SRCS))
OBJS=spectrum.o kiss_fft.o kiss_fftr.o oled.o mibridge.o
all: spectrum
spectrum: $(OBJS)
$(CXX) $(LDFLAGS) -o spectrum $(OBJS) $(LDLIBS)
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CXX) $(CPPFLAGS) $(CFLAGS) -MM $^>>./.depend;
clean:
#touch *
$(RM) $(OBJS)
$(RM) *~ .dependtool
$(RM) spectrum
print-%:
@echo '$*=$($*)'
include .depend
… и это (проблемный) Makefile, который я хотел использовать для кросс-компиляции:
TOOLCHAIN_PREFIX=$(HOME)/development/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-
SYSROOT=$(HOME)/development/raspberry/rootfs
CROSS_DIR=$(HOME)/development/raspberry/rootfs
CXX = $(TOOLCHAIN_PREFIX)g++
CC = $(TOOLCHAIN_PREFIX)gcc
LD = $(TOOLCHAIN_PREFIX)g++
RM=rm -f
INCLUDEDIR = ./
INCLUDEDIR += $(CROSS_DIR)/usr/include \
$(CROSS_DIR)/usr/include/arm-linux-gnueabihfLIBRARYDIR= $(CROSS_DIR)/lib \
$(CROSS_DIR)/lib/arm-linux-gnueabihf \
$(CROSS_DIR)/usr/lib/arm-linux-gnueabihf \
$(CROSS_DIR)/opt/vc/lib
XLINK_LIBDIR= $(CROSS_DIR)/lib \
$(CROSS_DIR)/lib/arm-linux-gnueabihf \
$(CROSS_DIR)/usr/lib/arm-linux-gnueabihf \
$(CROSS_DIR)/opt/vc/lib
LIBRARY= asound config++ configINCDIR = $(patsubst %,-I%,$(INCLUDEDIR))
LIBDIR = $(patsubst %,-L%,$(LIBRARYDIR))
LIB = $(patsubst %,-l%,$(LIBRARY))
XLINKDIR = $(patsubst %,-Xlinker -rpath-link=%,$(XLINK_LIBDIR))WARNINGS=-W -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-variable -Wno-unused-parameter -Wno-sequence-point -Wno-unused-but-set-variable -Wno-cast-alignOPT=-c -Wall -O3 -DFIXED_POINT=16 -DDEBUG=1 -DREAL_FASTFIR -DFAST_FILT_UTIL
OPT += -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
CFLAGS=-c -mfloat-abi=hardCXXFLAGS= $(OPT) $(WARNINGS) $(INCDIR)
LDFLAGS= $(LIBDIR) $(LIB) $(XLINKDIR) -lc -lm
SRCS=spectrum.cpp kiss_fft.c kiss_fftr.c oled.cpp mibridge.cpp
OBJS=spectrum.o kiss_fft.o kiss_fftr.o oled.o mibridge.oall: spectrum
spectrum: $(OBJS)
$(CXX) --sysroot=$(SYSROOT) $(LDFLAGS) $(OBJS) -o spectrum
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CXX) $(CXXFLAGS) $(CFLAGS) -MM $^>>./.depend;
clean:
#touch *
$(RM) $(OBJS)
$(RM) *~ .dependtool
$(RM) spectrum
print-%:
@echo '$*=$($*)'
include .depend
Единственное отличие, которое я вижу, это версия gcc:
на Ubuntu:
gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11)*
на RPI:
gcc version 4.6.3 (Debian 4.6.3-14+rpi1)*
Однако простой «Hello World» и первые дюжины строк исходного кода в моем приложении работают нормально.
Еще одно наблюдение:
Размер кода корзины на RPI: 59906
Размер кода корзины от креста: 121254
Похоже, что компоновщик что-то смешивает?
РЕДАКТИРОВАТЬ:
добавление результатов objdump -x
Есть некоторые отличия, я попытался выделить ниже два дампа:
Исполняемый файл ошибки сегментации имеет:
spectrum: file format elf32-little
architecture: UNKNOWN!, flags 0x00000112:
...
Dynamic Section:
...
NEEDED libc.so.6
NEEDED libgcc_s.so.1
...
SYMBOL TABLE:
...
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df *ABS* 00000000 /home/peter/development/raspberry/rootfs/usr/lib/arm-linux-gnueabihf/crt1.o
Версия RPI имеет много общего, но вот некоторые различия, которые я мог бы выяснить:
spectrum: file format elf32-littlearm
architecture: arm, flags 0x00000112:
...
Dynamic Section:
...
NEEDED libm.so.6
NEEDED libc.so.6
NEEDED libgcc_s.so.1
NEEDED libpthread.so.0
...
Version References:
...
required from libm.so.6: <---- mising in the cross-compiled version
0x0d696914 0x00 02 GLIBC_2.4
private flags = 5000002: [Version5 EABI] [has entry point]
...
Что еще интереснее в родной (рабочей) версии RPI, там полностью отсутствует ссылка на
crt1.o, crti.o, crtn.o,
Если вы предложите какую-то конкретную запись от objdump, это поможет мне узнать больше полезной информации.
РЕДАКТИРОВАТЬ 2
По рекомендации @yegorich я попробовал Трассирование и не нашел какой-либо конкретной полезной подсказки.
Однако я попытался отладить — просто чтобы увидеть, откуда происходит сегментация.
1. Скомпилируйте с -g -ggdb
2. Запустите GDB мое приложение
и результаты следующие:
Program received signal SIGSEGV, Segmentation fault.
0x0000d490 in demux(short*, short*, short*, CONFIG&) () at spectrum.cpp:530
530 if (PrgCfg.Sound_Channels[0] == 'M') {
Ничего особенно. Тот же код работает с нативно скомпилированным кодом без каких-либо проблем.
Я сделал некоторые изменения в коде, и затем код вылетает в другом месте — без «любой» возможной причины.
Затем я добавил «debug» printf, и одна из переменных изменила свое значение, в области я ничего не делаю с этим значением. Для меня четкий сигнал о том, что память была «повреждена» мой код.
Теперь я должен найти где — худшая ошибка за всю историю.
Я до сих пор не понимаю, почему этого не происходит, если я компилирую код с родным g ++.
Любая идея?
Любое предложение с вашей стороны очень ценится.
Спасибо.
Питер
Задача ещё не решена.