Segfault when calling llvm_sys' LLVMCreateTargetMachine to generate object file in Rust

三世轮回 提交于 2019-12-24 05:53:27

问题


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);
    }
}

error:

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

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?


回答1:


You are misunderstaning how to call LLVMGetTargetFromTriple:

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

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.

According to the LLVM docs:

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

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

(emphasis mine)

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



来源:https://stackoverflow.com/questions/37256726/segfault-when-calling-llvm-sys-llvmcreatetargetmachine-to-generate-object-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!