Two updates - see at the end of this post:
After two sleepless nights I decided (for the very first time) to directly ask for your support.
Problem:
When I try to cross-compile for Raspberry (RPI) a peace of code on my intel ubuntu it leads to the code which ends with a segmentation fault runtime error, when I run it on RPI
The same code compiled directly on the target RPI works just fine. The source code becomes to big to wait for compiling it on the RPI, therefore I wanted to accelerate the compilation on my Ubuntu.
Solution
1) follow the steps from http://elinux.org/RPi_Kernel_Compilation
2) Copy the "rootfs" from my target RPI including /lib /usr /opt
3) modify original project Makefile to point to the target libraries and include
4) enjoy fast compilation
Results:
Failed at the 4th point.
I can compile working kernel, modules and trivial Hello World application
I can compile my project and run it on RPI - it starts but always fails after a while with segmentation
fault. Very likely after first use of alsa lib.
Remarks:
I use in my project two external libraries -> -lasound -lconfig++ -lconfig and several own classes in separate files.
This is my standard Makefile, which produces working code on 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
... and this is the (problematic) Makefile I wanted to use for cross compiling:
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-gnueabihf
LIBRARYDIR= $(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++ config
INCDIR = $(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-align
OPT=-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=hard
CXXFLAGS= $(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.o
all: 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
The only difference I can see is the gcc version:
on Ubuntu:
gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11)*
on RPI:
gcc version 4.6.3 (Debian 4.6.3-14+rpi1)*
However simple "Hello World" and the first dozen of source code lines in my application work fine.
Another observation:
The bin code size on RPI is: 59906
The bin code size from cross is: 121254
Does it look like that the linker mixes something?
EDIT:
adding the results objdump -x
There are some differences, I tried to select in below two dumps:
Segmentation fault executable file has got:
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
The RPI version has many similarities, but these are some differences I could figure out:
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]
...
What is even more interesting in the RPI native (working) version there is completely missing reference to crt1.o, crti.o, crtn.o,
If you suggest any particular entry from objdump, it will help me to find out more useful information.
EDIT 2
As recommended by @yegorich i tried strace and did not found any particular useful hint.
However I tried to debug - just to see where the segmentation comes from.
1. Compile with -g -ggdb
2. Run gdb my application
and the results are as follow:
Program received signal SIGSEGV, Segmentation fault.
0x0000d490 in demux(short*, short*, short*, CONFIG&) () at spectrum.cpp:530
530 if (PrgCfg.Sound_Channels[0] == 'M') {
Nothing particular. The same code runs with natively compiled code without any problems. I did some changes in the code and the code crashes then in another point - without "any" feasible reason.
Then I added some "debug" printf and one of the variable changed its value, in scope I do nothing with this value. For me a clear signal that the memory has been "damaged" by my code.
Now I have to find where - the worst error ever.
I still do not understand why it does not happen if I compile the code with a native g++. Any idea?
Any suggestion from your side is very appreciated.
Thank you.
Peter
User contributions licensed under CC BY-SA 3.0