You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用-Wl,-z,nocopyreloc编译程序后运行触发段错误求助

问题分析与解决方案

核心原因:-z nocopyreloc与Raspbian Stretch运行时的兼容性冲突

我之前在armhf架构的嵌入式系统上碰到过类似问题,核心矛盾是你用的链接器选项和目标系统的运行时环境不兼容。先拆解下关键点:

你添加的-Wl,-z,nocopyreloc是GNU链接器的选项,作用是禁止生成需要动态拷贝的重定位项(copy relocations)。这类重定位主要用于处理共享库中的可写全局变量——动态链接器需要把这些变量从共享库拷贝到进程私有内存,保证进程间的变量隔离。

但在你的场景里:

  • Raspbian Stretch搭配gcc 6.3.0,对应的glibc版本(一般是2.24)在armhf架构下,线程初始化逻辑(因为你链接了-lpthread)或者C运行时的全局初始化代码,依赖copy relocations才能完成加载。
  • 当你强制禁用这类重定位后,动态链接器在加载程序时无法完成必要的内存重定位操作,直接在进入main函数之前触发了段错误。

解决方案

  1. 直接移除-z nocopyreloc选项
    这是最快速有效的解决方式,因为你的目标系统运行时天生依赖这类重定位,强行禁用会破坏程序加载的兼容性。修改后的编译命令:

    pi@raspberrypi:/tmp $ arm-linux-gnueabihf-g++ -g -Wall -O0 -ggdb segfault_check.cpp -o segv_test -lpthread
    
  2. 用兼容选项替代(如果需要安全/优化特性)
    如果你是为了安全或优化目的才用-z nocopyreloc,可以换成更兼容的组合:

    • -z relro:标记只读重定位段,减少可被利用的内存区域
    • -z now:强制在加载阶段完成所有动态重定位,避免延迟绑定的安全风险
      组合后的命令:
    pi@raspberrypi:/tmp $ arm-linux-gnueabihf-g++ -g -Wall -O0 -ggdb -Wl,-z,relro,-z,now segfault_check.cpp -o segv_test -lpthread
    
  3. 升级系统(可选)
    如果设备允许,升级到更新的Raspbian版本(比如Buster或Bookworm),新版本的glibc和链接器对-z nocopyreloc的支持更完善,能更好地适配这类禁用操作。

内容的提问来源于stack exchange,提问作者djf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:17:39