在 Rust 中调用 llvm_sys' LLVMCreateTargetMachine 生成目标文件时出现段错误
Segfault when calling llvm_sys' LLVMCreateTargetMachine to generate object file in 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.[=11=]".as_ptr() as *mut i8].as_mut_ptr());
let cpu = "x86[=11=]".as_ptr() as *const i8;
let feature = "[=11=]".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[=11=]".as_ptr() as *mut i8, file_type, "Cannot generate file.[=11=]".as_ptr() as *mut *mut i8);
}
}
pub fn main() {
use Term::*;
unsafe {
let module = LLVMModuleCreateWithName("Main[=11=]".as_ptr() as *const i8);
emit(module);
}
}
错误:
Process didn't exit successfully: `target/debug/ende` (signal: 11, SIGSEGV: invalid memory reference)
我正在编写我的玩具编译器,现在我想生成目标文件。
为什么上面的代码会产生段错误?
我怎么知道我做错了什么?
是否有可能获得堆栈跟踪?
我没有使用 C/C++ 的经验,所以我不知道如何调试。
问题与target
有关吗?
你误解了如何调用LLVMGetTargetFromTriple
:
pub unsafe extern "C" fn LLVMGetTargetFromTriple(Triple: *const c_char,
T: *mut LLVMTargetRef,
ErrorMessage: *mut *mut c_char)
-> LLVMBool
此函数接受一个指向 C 风格字符串的指针,该字符串将在出现错误时被填充。该方法实际成功由结果报告。
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.
(强调我的)
现在,该调用失败,因此目标 ref 从未初始化,因此您正试图在未定义的代码上调用方法。
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.[=11=]".as_ptr() as *mut i8].as_mut_ptr());
let cpu = "x86[=11=]".as_ptr() as *const i8;
let feature = "[=11=]".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[=11=]".as_ptr() as *mut i8, file_type, "Cannot generate file.[=11=]".as_ptr() as *mut *mut i8);
}
}
pub fn main() {
use Term::*;
unsafe {
let module = LLVMModuleCreateWithName("Main[=11=]".as_ptr() as *const i8);
emit(module);
}
}
错误:
Process didn't exit successfully: `target/debug/ende` (signal: 11, SIGSEGV: invalid memory reference)
我正在编写我的玩具编译器,现在我想生成目标文件。
为什么上面的代码会产生段错误?
我怎么知道我做错了什么?
是否有可能获得堆栈跟踪?
我没有使用 C/C++ 的经验,所以我不知道如何调试。
问题与target
有关吗?
你误解了如何调用LLVMGetTargetFromTriple
:
pub unsafe extern "C" fn LLVMGetTargetFromTriple(Triple: *const c_char,
T: *mut LLVMTargetRef,
ErrorMessage: *mut *mut c_char)
-> LLVMBool
此函数接受一个指向 C 风格字符串的指针,该字符串将在出现错误时被填充。该方法实际成功由结果报告。
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.
(强调我的)
现在,该调用失败,因此目标 ref 从未初始化,因此您正试图在未定义的代码上调用方法。