代码之家  ›  专栏  ›  技术社区  ›  bremen_matt

确定导致pi zero w(armv6)上“非法指令”的库,并修复生成

  •  -1
  • bremen_matt  · 技术社区  · 6 年前

    我知道很多关于pi-zero的编译问题都是因为它们使用了armv6,而更新的覆盆子pi像3a+和b+使用armv7。但是,我不理解如何在导致问题的应用程序中找到有问题的库,以及是否有解决问题的简单方法。

    背景:

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

    但是,pi-zero实现会编译,但运行时只会发出一条消息:

    Illegal instruction
    

    这很可能是由于某些命令与ARMV6不兼容,但我无法确定这是哪个命令。我想先确定哪个图书馆是问题儿童。请告诉我如何诊断。

    额外信息:

    我已经检查过编译器不是问题所在。怎样?我做了一个简单的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
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Chris Stratton    6 年前

    识别故障,如 Illegal instruction 您可以在能够与操作系统的故障处理程序交互的调试器下运行程序。

    在Linux系统上,比如pi gdb . 您可能需要在Debian派生的发行版上安装此软件, sudo apt-get install gdb

    然后运行程序

    gdb myprog
    

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

    gdb myprog --args some_argument another_argument
    

    一次 GDB 启动型 run ,程序将在接近正常的情况下执行,直到达到非法指令为止,此时您将在gdb提示符处被转储回一条希望提供信息的错误消息。

    在那里,您可以使用诸如 backtrace 或者如果程序员有关联的源, list . 如果故障在一个地址,gdb可以看到从一个文件映射而来,它应该向您显示——您也可以通过gdb命令获取映射信息。 info files 或者通过观察 /proc/[PID]/maps

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


    根据系统配置,如果单独运行程序 没有 作为调试器,您还可以在 dmesg 或其他系统日志。