确定在 Pi Zero W (armv6) 上导致 "Illegal instruction" 的库,并修复构建

Determining the library which causes "Illegal instruction" on a Pi Zero W (armv6), and fixing the build

我知道 Pi Zeros 上的很多编译问题是由于它们使用 armv6,而较新的 Raspberry Pi 像 3 A+ 和 B+ 使用 armv7。但是,我不明白如何在导致问题的应用程序中找到有问题的库,以及是否可能有一个简单的解决方法来解决这个问题。

背景:

我正在尝试将应用程序从 Linux 桌面环境移植到 Pi Zero (运行ning armv6)。我成功地将它移植到 Pi 3 B 和 B+。也就是说,我编译了代码,并检查它是否产生了正确的输出。

然而,Pi Zero 实现编译,但在 运行:

时仅吐出一条消息
Illegal instruction

这很可能是由于某些命令与 armv6 不兼容,但我无法确定是哪个命令。我想首先确定问题出在哪个库 child。请告诉我如何诊断。

额外信息:

我已经检查过编译器不是问题所在。如何?我做了一个简单的 hello world 程序,并为 Pi Zero 编译了它:

#include<iostream>

int main(int argc, char *argv[]){
   std::cout << "Hello World!" << std::endl;
   return 0;
}

所以编译器本身似乎不是问题所在。

更多详情:

如果我 运行 readelf -A myapp,我的理解是输出报告该应用确实是为 armv6 编译的:

Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "6"
  Tag_CPU_arch: v6
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_FP_arch: VFPv2
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6

这是共享库之一的 readelf -A

Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "6"
  Tag_CPU_arch: v6
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_FP_arch: VFPv4
  Tag_Advanced_SIMD_arch: NEONv1 with Fused-MAC
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: Deprecated
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6

要识别诸如 Illegal instruction 之类的错误,您可以 运行 在能够与操作系统的错误处理程序交互的调试器下运行程序。

在像 pi 这样的 Linux 系统上,那将是 gdb。您可能需要在 sudo apt-get install gdb

的 debian 派生发行版上安装它

然后运行你的程序

gdb myprog

或者如果您的程序需要命令行参数

gdb myprog --args some_argument another_argument

一旦 gdb 启动类型 run,程序将接近正常执行,直到它到达非法指令,此时您将被转回 gdb 提示符,希望提供信息错误信息。

您可以在那里使用 backtrace 等命令进行探索,或者如果程序员有关联的源,list。如果故障出在 gdb 可以看到的地址,因为它是从文件映射的,它应该会告诉你——你也可以通过 gdb 命令 info files 或查看 /proc/[PID]/maps[ 来获取映射信息。 =22=]

如果由于某种原因你不能 运行 程序在 gdb 下运行,你可以研究如何为你的系统启用核心转储,然后将程序和核心转储加载到 gdb 中 post-验尸分析。


根据系统配置,如果 运行 在没有 调试器的情况下 运行 自行运行程序 ,您还可以在 dmesg 或其他系统日志。