Segfault when calling llvm_sys' LLVMCreateTarg

2019-07-25 12:59发布

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条回答
家丑人穷心不美
2楼-- · 2019-07-25 13:41

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.

查看更多
登录 后发表回答