Необычный segfault при использовании C ++ Std Lib на встроенном Linux

Вот пример тестового кода, который я пытаюсь запустить на встроенной системе Linux:

#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;
}

Встроенная система представляет собой Microblaze, 32-битный программный процессор RISC, работающий на Xilinx FPGA. Пожалуйста, не отчаивайтесь, так как многие ваши стандартные знания Linux все еще будут применяться. Процессор настроен как LSB с MMU, и сборка Linux, которую я использую (PetaLinux, поставляется Xilinx), ожидает того же. Я использую прилагаемый компилятор GNU; Microblaze официально поддерживается в GCC.

У меня проблема в том, что когда stdlib должен взаимодействовать с целым числом, он segfaults. Вот вывод:

Hello World from C++
c=A
Segmentation fault

Обратите внимание, что символ обрабатывается нормально. C-эквивалент этого кода также отлично работает:

#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

Это заставляет меня подозревать проблему с общей библиотекой libstdc++.so.6.0.20, Эта библиотека поставляется Xilinx, поэтому она должна быть правильной. file вывод этой библиотеки:

libstdc++.so.6.0.20: ELF 32-bit LSB shared object, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, not stripped

file вывод моего двоичного файла:

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

Я также пытался статически связать мой бинарный файл, используя -static флаг, но результат был тот же.

Вот наиболее важные настройки компилятора и компоновщика, которые я использую, но я попытался изменить их безрезультатно.

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)

Обратите внимание, что microblazeel относится к младшей порядковой версии компилятора microblaze.

Я бы очень хотел отладить это или, по крайней мере, взглянуть на coredump, но кажется, что coredump не создается, когда происходит segfault, и нет gdb исполняемый файл в сборке Microblaze Linux. Может я что-то упустил?

Спасибо, что нашли время, чтобы прочитать это. Какие-нибудь мысли?

5

Решение

Из того, что я увидел после небольшого исследования, vivado это IDE разработки HW [потому что они предлагают пробный период — так что это HW devel, за который они всегда хотят взимать плату].

Если вы используете стандартный SDK доска от Xilinx все должно быть предварительно настроено. В противном случае, конструктор HW производит конструкцию HW, в которой есть Microblaze.

Исходя из этого, вам, возможно, придется использовать petalinux для создания нового образа загрузки, ядра и т. Д., Который совместим.

Вы может нужно восстановить libstdc++ из источника, но я бы сделал это в крайнем случае. Например, не беспокойтесь, пока не получите gdb работают и имеют результаты испытаний.


Вот некоторые файлы Petalinux PDF:
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug977-petalinux-getting-started.pdf
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug981-petalinux-application-development-debug.pdf


Руководство по разработке показывает, как вызвать GDB (например):
В целевой системе:
gdbserver host:1534 /bin/myapp
По системе разработки:
petalinux-utils --gdb myapp с последующим target remote 192.168.0.10:1534


Я сделал некоторые изменения в вашем Makefile с аннотациями. Я закомментировал некоторые несущественные варианты. Обратите внимание, что я использую += оператор построить CFLAGS/CXXFLAGS постепенно

Основная идея здесь — сделать сборку с минимальными отклонениями от «стандартного». Добавляйте только проверенные основные опции. Сборка и тестирование. Добавляйте опции по одному [перестраивайте и тестируйте каждый раз], пока не найдете вариант, вызывающий проблему.

У меня, однако, есть сильное подозрение о -fno-common быть источником проблем. Кроме того, в меньшей степени, я немного подозрительно -Wl,--as-needed

Должны ли эти варианты работать? Конечно, но xilinx / microblaze не x86 …

Я добавил две переменные make командной строки:
DEBUG — генерировать для отладки с помощью GDB
VERBOSE — показать все о процессе сборки

Например, попробуйте make <whatever> DEBUG=1 VERBOSE=1

CC = microblazeel-xilinx-linux-gnu-gcc
CXX = microblazeel-xilinx-linux-gnu-g++

CPPFLAGS ?=

CMFLAGS += -Wall -Werror
CMFLAGS += -fmessage-length=0

# compile for gdb session
# NOTES:
# (1) -gdwarf-2 may or may not be the the right option for microblaze
# (2) based on doc for -feliminate-unused-debug* petalinux/microblaze may want
#     stabs format
ifdef DEBUG
CMFLAGS += -gdwarf-2
CMFLAGS += -O0

# compile for normal build
#else
CMFLAGS += -O2
CMFLAGS += -feliminate-unused-debug-types
endif

# NOTE: I used to use "@" on commands, but now I leave it off -- debug or not
# sure it's "ugly" but you can get used to it pretty quickly--YMMV
ifndef VERBOSE
Q :=
else
###Q := @
Q :=
endif

# let compiler/linker tell you _everything_:
# (1) configure options when tool was built
# (2) library search paths
# (3) linker scripts being used
ifdef VERBOSE
CMFLAGS += -v
LDFLAGS += -Wl,--verbose=2
endif

CMFLAGS += -fno-builtin

# NOTE: I'd _really_ leave this off as it may confuse c++ std as "<<" calls
# _M_insert (which is in the library, which is almost certainly _not_ using
# -fno-common)
###CMFLAGS += -fno-common

# NOTE: I'm also suspicious of this a little bit because the c++ lib may have
# some "weak" symbols that the c library doesn't
###LDFLAGS += -Wl,--as-needed

# NOTE: this seems harmless enough, but you can comment it out to see if it
# helps
LDFLAGS += -Wl,--hash-style=gnu

# NOTE: an optimization only
ifndef DEBUG
LDFLAGS += -Wl,-O1
endif

CFLAGS += $(CMFLAGS)
CXXFLAGS += $(CMFLAGS)

# NOTES:
# (1) leave this off for now -- doesn't save _that_ much and adds complexity
#     to the build
# (2) IMO, I _never_ use it and I erase/uninstall it on any system I
#     administrate (or just ensure the build doesn't use it by removing it
#     from $PATH)--YMMV
###XCCACHE = $(CCACHE)

# to compile
$(Q)$(XCCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$@"
# to link
$(Q)$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
1

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

Других решений пока нет …

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