Makefile for nontrivial hello world cross building leads to segemnation fault on Raspberry

1

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

c++
makefile
raspberry-pi
cross-compiling
toolchain
asked on Stack Overflow Oct 6, 2014 by Peter • edited Oct 8, 2014 by Peter

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0