调用llvm_sys的LLVMCreateTargetMachine在Rust中生成目标文件时出现段错误 [英] Segfault when calling llvm_sys' LLVMCreateTargetMachine to generate object file in Rust

查看:312
本文介绍了调用llvm_sys的LLVMCreateTargetMachine在Rust中生成目标文件时出现段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

extern crate llvm_sys;

use llvm_sys::*;
use llvm_sys::prelude::*;
use llvm_sys::core::*;

pub fn emit(module: LLVMModuleRef) {
    unsafe {
        use llvm_sys::target_machine::*;
        let triple = LLVMGetDefaultTargetTriple();
        let mut target: LLVMTargetRef = std::mem::uninitialized();
        LLVMGetTargetFromTriple(triple, &mut target, ["Cannot get target.\0".as_ptr() as *mut i8].as_mut_ptr());
        let cpu = "x86\0".as_ptr() as *const i8;
        let feature = "\0".as_ptr() as *const i8;
        let opt_level = LLVMCodeGenOptLevel::LLVMCodeGenLevelNone;
        let reloc_mode = LLVMRelocMode::LLVMRelocDefault;
        let code_model = LLVMCodeModel::LLVMCodeModelDefault;
        let target_machine = LLVMCreateTargetMachine(target, triple, cpu, feature, opt_level, reloc_mode, code_model);

        let file_type = LLVMCodeGenFileType::LLVMObjectFile;

        // LLVMTargetMachineEmitToFile(target_machine, module, "/Users/andyshiue/Desktop/main.o\0".as_ptr() as *mut i8, file_type, "Cannot generate file.\0".as_ptr() as *mut *mut i8);
    }
}

pub fn main() {
    use Term::*;

    unsafe {
        let module = LLVMModuleCreateWithName("Main\0".as_ptr() as *const i8);
        emit(module);
    }
}

错误:

Process didn't exit successfully: `target/debug/ende` (signal: 11, SIGSEGV: invalid memory reference)

我正在编写我的玩具编译器,现在我想生成目标文件. 为什么上面的代码会产生段错误? 我怎么知道我做错了什么? 是否可以获取堆栈跟踪? 我没有C/C ++的经验,所以我不知道如何调试. 问题与target有关吗?

I'm writing my toy compiler, and now I want to generate object files. Why is the code above producing segfault? How do I know what I'm doing wrong? Is it possible to get a stack trace? I don't have experience with C/C++, so I don't know how to debug. Does the problem have something to do with target?

推荐答案

您误解了如何调用LLVMGetTargetFromTriple:

pub unsafe extern "C" fn LLVMGetTargetFromTriple(Triple: *const c_char,
                                                 T: *mut LLVMTargetRef,
                                                 ErrorMessage: *mut *mut c_char)
                                                 -> LLVMBool

此函数接受一个指向C样式的字符串的指针,该字符串在发生错误的情况下将被填充.结果报告了该方法的实际成功.

This function accepts a pointer to a C-style string that will be filled in in case of error. The actual success of the method is reported by the result.

根据 LLVM文档:

查找与给定三元组对应的目标并将其存储在T中.

Finds the target corresponding to the given triple and stores it in T.

成功返回0 . (可选)在ErrorMessage中返回任何错误.使用LLVMDisposeMessage来处理消息.

Returns 0 on success. Optionally returns any error in ErrorMessage. Use LLVMDisposeMessage to dispose the message.

(重点是我的)

现在,该调用失败,因此永远不会初始化目标ref,因此您试图在未定义的代码上调用方法.

Right now, that call is failing, thus the target ref is never initialized, thus you are trying to call methods on undefined code.

这篇关于调用llvm_sys的LLVMCreateTargetMachine在Rust中生成目标文件时出现段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆