Here's some 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 a Microblaze, which is a 32-bit RISC softcore processor running on a Xilinx FPGA. Please don't be put off by that, as a lot of your standard Linux knowledge will still apply. The processor is configured as LSB with an MMU, and the Linux build I'm using (PetaLinux, supplied by Xilinx) is expecting the same. I'm using the supplied GNU compiler; Microblaze appears to be officially supported in GCC.
The problem I'm having is that when the stdlib needs to interact with the integer, it segfaults. Here's the output:
Hello World from C++
c=A
Segmentation fault
Note that the char is handled 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 leads me to suspect an issue with the shared library libstdc++.so.6.0.20
. That library is supplied by Xilinx though, so it should be correct. The file
output of that 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
The file
output of my binary is:
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've also tried statically linking my binary using the -static
flag, but the result was the same.
Here are the most relevant compiler and linker settings I'm using, but I've tried changing these with 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 the little endian version of the microblaze compiler.
I would very much like to debug this or at least look at a coredump, but no coredump seems to be produced when the segfault happens, and there's no gdb
executable in the Microblaze Linux build. Maybe I'm missing something?
Thanks for taking your time to read this. Any thoughts?