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

LLVM生成Bitcode执行触发访问违例,求代码修复方案

问题修复方案

错误原因分析

触发"Access violation reading location 0x0000000000000000"的核心原因有两个:

  1. LLVM初始化不完整:缺少必要的目标架构组件初始化,导致ExecutionEngine创建失败返回nullptr,后续调用engine->runFunction时访问空指针。
  2. 未检查ExecutionEngine创建结果:没有判断create()的返回值是否有效,直接调用成员函数引发空指针访问。

修复后的完整代码

#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/EngineBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

void Execute()
{
    // 补充完整的LLVM目标架构初始化
    LLVMInitializeNativeTarget();
    LLVMInitializeNativeAsmPrinter();
    LLVMInitializeNativeAsmParser();
    LLVMInitializeNativeTargetMC();

    LLVMContext context;
    std::unique_ptr<Module> mods = std::make_unique<Module>("fnc", context);
    Module* mod = mods.get();

    FunctionType* add_func_type = FunctionType::get(Type::getInt32Ty(context), { Type::getInt32Ty(context), Type::getInt32Ty(context) }, false);
    Function* func = Function::Create(add_func_type, Function::ExternalLinkage, "add", mod);

    // 为函数参数命名(可选,提升调试可读性)
    auto arg_iter = func->arg_begin();
    Value* x = &*arg_iter++;
    x->setName("x");
    Value* y = &*arg_iter++;
    y->setName("y");

    BasicBlock* entry = BasicBlock::Create(context, "entry", func);
    IRBuilder<> builder(entry);
    Value* sum = builder.CreateAdd(x, y, "sum");
    builder.CreateRet(sum);

    // 校验模块并输出错误信息
    if (verifyModule(*mod, &llvm::errs())) {
        llvm::errs() << "模块校验失败\n";
        return;
    }

    // 创建ExecutionEngine并检查有效性
    std::unique_ptr<ExecutionEngine> engine(EngineBuilder(std::move(mods)).create());
    if (!engine) {
        llvm::errs() << "ExecutionEngine创建失败\n";
        return;
    }

    std::vector<GenericValue> args(2);
    args[0].IntVal = APInt(32, 2);
    args[1].IntVal = APInt(32, 3);
    GenericValue result = engine->runFunction(func, args);

    // 打印执行结果
    llvm::outs() << "2 + 3 = " << result.IntVal.getZExtValue() << "\n";
}

关键修复点说明

  • 补充初始化:添加LLVMInitializeNativeAsmParser和LLVMInitializeNativeTargetMC,确保ExecutionEngine能正确生成目标机器码。
  • 空指针检查:在使用engine前判断其是否为nullptr,避免空指针访问。
  • 优化模块校验:将verifyModule的错误输出定向到llvm::errs(),便于排查模块合法性问题。
  • 参数命名(可选):给函数参数命名,提升IR代码的可读性和调试便利性。

内容的提问来源于stack exchange,提问作者Kashikoi Clev-san

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:15:42