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

JIT编译的LLVM IR在FreeBSD下无法调用主程序C函数(MacOS可正常运行)的问题求助

FreeBSD下LLVM JIT无法访问主程序本地函数的解决办法

你的判断完全正确——这个问题确实和FreeBSD的链接器/运行时加载器行为有关,和MacOS的默认行为差异导致了兼容性问题。我来帮你拆解原因并给出具体的解决步骤:

问题根源

FreeBSD的系统链接器ld和运行时加载器ld.so默认不会把主程序(可执行文件)的全局符号导出到动态符号表中,而LLVM JIT生成的代码本质上是在运行时动态加载的“临时共享库”,它只能从动态符号表中查找外部符号。

而MacOS的dyld(动态加载器)默认允许动态加载的代码直接查找主程序的符号,所以你的代码在Mac上能正常运行,但到FreeBSD就会因为找不到test_fun的符号而崩溃。

问题复现代码

示例C++代码

// 省略头文件
extern "C" {
int test_fun(int arg) {
    printf("Super test fun %d\n", arg);
    return arg + 1;
}
}
int main(int ac, char **av) {
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();
    InitializeNativeTargetAsmParser();
    llvm::LLVMContext ctx;
    llvm::SMDiagnostic diag;
    auto M = parseIRFile( av[1], diag, ctx );
    printf("Module %llx\n", (uint64_t)M.get());
    std::string err;
    llvm::EngineBuilder EB(std::move(M));
    EB.setEngineKind(llvm::EngineKind::JIT).setErrorStr(&err);
    llvm::ExecutionEngine* EE = EB.create();
    if (!EE) return 0;
    EE->finalizeObject();
    const auto fa = (int(*)())EE->getFunctionAddress(av[2]);
    printf("IR fun '%s' returned %d\n", av[2], fa());
    return 0;
}

示例IR代码

declare i32 @test_fun(i32)
define i32 @test_ll() {
    %v1 = mul i32 4, 5
    %v2 = add i32 3, %v1
    %v3 = call i32(i32) @test_fun(i32 %v2)
    ret i32 %v3
}

解决方案

有两种可靠的方式解决这个问题,你可以根据需求选择:

1. 编译主程序时导出所有全局符号(推荐)

在编译主程序时添加链接选项-Wl,-E(或者兼容GCC的-export-dynamic),这个选项会告诉链接器把所有全局符号都导出到动态符号表,让JIT代码可以访问。

比如你的编译命令可以改成:

clang++ -o jit_test jit_test.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core native` -Wl,-E

2. 显式标记单个函数为可导出

如果你不想导出所有符号,只需要让特定函数被JIT访问,可以给函数添加visibility("default")属性,强制它被导出到动态符号表:

修改你的C++代码中的test_fun:

extern "C" {
__attribute__((visibility("default")))
int test_fun(int arg) {
    printf("Super test fun %d\n", arg);
    return arg + 1;
}
}

这种方式不需要修改编译选项,但需要给每个要被JIT调用的函数都添加属性,适合符号数量较少的场景。

验证效果

用上述任意一种方式修改后,重新编译主程序,再运行测试:

./jit_test test.ll test_ll

此时JIT生成的代码应该能正常找到并调用主程序中的test_fun,程序不再崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:57:33