Makefile для нетривиального кросс-билдинга «Привет, мир» приводит к ошибкам в сегментации малины

Два обновления — смотрите в конце этого поста:

После двух бессонных ночей я решила (впервые) напрямую обратиться за вашей поддержкой.

проблема:
Когда я пытаюсь выполнить кросс-компиляцию для 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 ++.
Любая идея?


Любое предложение с вашей стороны очень ценится.
Спасибо.
Питер

1

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]