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

如何手动向lld提供core::panicking::panic*符号解决Rust C混编链接错误

问题根因

你遇到的链接错误是因为编译Rust代码时仅导出了自身代码的LLVM IR,没有把core库中core::panicking相关的依赖实现一同带入链接流程,哪怕你已经定义了panic_handler,core库内部的panic入口包装函数仍然是缺失状态。

解决方法

方法1:补全Rust侧编译流程,携带core依赖

你的cargo rustc命令缺少目标架构指定,且仅导出自身代码IR,没有包含core库的编译产物:

  1. 首先准备好MOS 6502对应的Rust目标描述JSON文件,编译时指定目标:
cargo rustc --release --target=mos-6502.json -- -C debuginfo=0 -C opt-level=1 --emit=obj

不要用--emit=llvm-ir,直接编译为.o目标文件,rustc会自动将你定义的panic_handler与core库的panic入口做关联,不会再产生外部符号依赖。
2. 把编译生成的目标文件(路径为target/mos-6502/release/deps/chip8_c64-xxxxxx.o)替换原来的.ll文件传给clang链接即可。

方法2:手动指定符号别名(快速兜底)

如果你不想修改现有编译流程,可以直接在最后一步clang链接时通过链接器参数将缺失的符号指向你已经实现的panic处理函数:

llvm-mos/bin/clang --config llvm-mos-sdk/build/commodore/64.cfg \
    -O2 \
    -o _build/charset.prg \
    _build/main.c.o \
    target/release/deps/chip8_c64-e21ff59526dd729a.ll \
    -Wl,--defsym=core::panicking::panic_bounds_check::hc3a71010bf41c72d=panic,--defsym=core::panicking::panic::hd695e3b1d0dd4ef4=panic

这里的panic就是你定义的panic_handler函数名,链接器会直接把缺失的符号指向该函数,不会再报未定义错误。

方法3:手动实现缺失符号

直接在你的Rust代码中用#[no_mangle]强制导出缺失的符号,指向你的panic逻辑:

use core::panic::PanicInfo;

#[panic_handler]
pub extern fn panic(_: &PanicInfo<'_>) -> ! {
    loop{}
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "Rust" fn core::panicking::panic_bounds_check::hc3a71010bf41c72d(_: usize, _: usize) -> ! {
    panic()
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "Rust" fn core::panicking::panic::hd695e3b1d0dd4ef4(_: &'static str, _: u32) -> ! {
    panic()
}

注意函数参数要和core中对应panic函数的参数匹配,避免调用时栈出错。

额外注意

  • 建议在.cargo/config.toml中全局配置panic策略,确保跨目标生效:
[target.'cfg(all())']
panic = "abort"
  • 尽量不要直接传递LLVM IR做跨语言链接,使用编译完成的目标文件可以避免很多符号关联问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:30:03