Here is a sample test code I'm trying to run on an embedded Linux system:
#include <iostream> int main(int argc, char *argv[]) { char c = 'A'; int i = 7; std::cout << "Hello World from C++" << std::endl; std::cout << "c=" << c << std::endl; std::cout << "i=" << i << std::endl; }
The embedded system is Microblaze, which is a 32-bit RISC software processor running on Xilinx FPGAs. Please do not delay, as many of your standard Linux knowledge will continue to be applied. The processor is configured as LSB with MMU, and the Linux build I use (PetaLinux, supplied by Xilinx) expects the same. I use the included GNU compiler; Microblaze appears to be officially supported by GCC.
The problem I am facing is that when stdlib needs to interact with an integer, it segfaults. Here's the conclusion:
Hello World from C++ c=A Segmentation fault
Note that char handles fine. The C-equivalent of this code also works fine:
#include <stdio.h> int main(int argc, char *argv[]) { char c = 'A'; int i = 7; printf("Hello World from C\n"); printf("c=%c\n", c); printf("i=%i\n", i); return 0; }
...
Hello World from C c=A i=7
This makes me suspect a problem with the libstdc++.so.6.0.20 shared library. However, this library is supplied by Xilinx, so it must be correct. The output of the file this library is:
libstdc++.so.6.0.20: ELF 32-bit LSB shared object, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, not stripped
file output of my binary:
cpptest: ELF 32-bit LSB executable, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped
I also tried to statically link my binary using the -static flag, but the result was the same.
Here are the most suitable compiler and linker settings that I use, but I tried to change them to no avail.
CC=microblazeel-xilinx-linux-gnu-gcc CXX=microblazeel-xilinx-linux-gnu-g++ CFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types CPPFLAGS?= CXXFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types LDFLAGS=-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed To compile: @$(CCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o " $@ " To link: @$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
Note that microblazeel refers to a small continental version of the microblaze compiler.
I would really like to debug this, or at least look at coredump, but no coredump seems to be created when segfault happens and there is no gdb executable in the Microblaze Linux build. Maybe I missed something?
Thanks for taking the time to read this. Any thoughts?