加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

在嵌入式Linux上使用C Std Lib时出现异常的段错误

发布时间:2020-12-14 01:43:55 所属栏目:Linux 来源:网络整理
导读:这是我试图在嵌入式 Linux系统上运行的一些示例测试代码: #include iostreamint 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;} 嵌入式系
这是我试图在嵌入式 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,它是在Xilinx FPGA上运行的32位RISC软核处理器.请不要因为你的许多标准Linux知识仍然适用而被推迟.处理器配置为带有MMU的LSB,而我正在使用的Linux版本(由Xilinx提供的PetaLinux)期望相同.我正在使用提供的GNU编译器; Microblaze似乎在GCC正式支持.

我遇到的问题是,当stdlib需要与整数进行交互时,会出现段错误.这是输出:

Hello World from C++
c=A
Segmentation fault

请注意,char处理得很好.这段代码的C等效也可以正常工作:

#include <stdio.h>

int main(int argc,char *argv[])
{
    char c = 'A';
    int i = 7;

    printf("Hello World from Cn");
    printf("c=%cn",c);
    printf("i=%in",i);

    return 0;
}

Hello World from C
c=A
i=7

这导致我怀疑共享库libstdc .so.6.0.20存在问题.该库是由Xilinx提供的,所以它应该是正确的.该库的文件输出是:

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

我的二进制文件的文件输出是:

cpptest: ELF 32-bit LSB executable,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是指微藻类编译器的小端版本.

我非常想调试这个或者至少看一下coredump,但是当segfault发生时似乎没有产生coredump,并且在Microblaze Linux版本中没有gdb可执行文件.也许我错过了什么?

感谢您抽出宝贵时间阅读本文.有什么想法吗?

解决方法

通过一些研究后我可以看到,vivado是硬件开发IDE [因为它们提供了一个试用期 – 所以它是硬件开发,他们总是想要收费].

如果您使用的是Xilinx的标准SDK板,则应该预先配置所有内容.否则,硬件设计师会生成一个具有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主机:1534 / bin / myapp
在开发系统上:
??petalinux-utils –gdb myapp后跟目标远程192.168.0.10:1534

我已经使用注释对Makefile进行了一些编辑.我已经评论了一些非必要的选项.请注意,我正在使用=运算符逐渐构建CFLAGS / CXXFLAGS

这里的基本思想是以最小的“标准”偏差进行构建.仅添加经过验证的基本选项构建和测试.逐个添加选项[每次重建和测试],直到找到导致问题的选项.

然而,我确实怀疑 – 共同 – 是一个问题的根源.此外,在较小的程度上,我有点怀疑-Wl,– 根据需要

这些选项应该有效吗?当然,但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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读