From fd8b8eaacb2656c61022d66060b39887d3ba378e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABlle=20MARTIN?= <maelle.martin@proton.me> Date: Wed, 21 Aug 2024 18:22:05 +0200 Subject: [PATCH] SCRIPT: Fixed some segv - Borrowing llvm context, don't dispose of it - Didn't init all the needed things for the JIT - Incorrect buffer size for the random generator - Log what's happening in the temp/lock file thing --- src/Rust/.gitignore | 1 + src/Rust/vvs_llvm/src/bindings/context.rs | 10 +++++++--- src/Rust/vvs_llvm/src/bindings/function.rs | 2 +- src/Rust/vvs_llvm/src/bindings/module.rs | 10 ++++++++++ src/Rust/vvs_llvm/src/init.rs | 6 ++++++ src/Rust/vvs_runtime/src/jit.rs | 11 +++-------- src/Rust/vvs_utils/src/rand.rs | 4 ++-- src/Rust/vvs_xdg/src/file/lock.rs | 23 ++++++++++++++-------- src/Rust/vvs_xdg/src/file/temp.rs | 1 + 9 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 src/Rust/.gitignore diff --git a/src/Rust/.gitignore b/src/Rust/.gitignore new file mode 100644 index 00000000..78fb1fce --- /dev/null +++ b/src/Rust/.gitignore @@ -0,0 +1 @@ +.gdb_history diff --git a/src/Rust/vvs_llvm/src/bindings/context.rs b/src/Rust/vvs_llvm/src/bindings/context.rs index 88c01d3c..a9aadfcf 100644 --- a/src/Rust/vvs_llvm/src/bindings/context.rs +++ b/src/Rust/vvs_llvm/src/bindings/context.rs @@ -5,7 +5,9 @@ use std::{ marker, }; -crate::bindings::declare! { mut LLVMContextRef as Context<'a> } +crate::bindings::declare! { mut LLVMContextRef as Context<'a> { + borrowed: bool, +} } macro_rules! get_type { ($llvm:ident as $name:ident) => { @@ -32,7 +34,7 @@ impl Context<'_> { // aborted the program. log::debug!("{err}"); } - Self { inner: unsafe { LLVMContextCreate() }, marker: marker::PhantomData } + Self { inner: unsafe { LLVMContextCreate() }, borrowed: false, marker: marker::PhantomData } } /// Create a new builder for this context. @@ -60,6 +62,8 @@ impl Context<'_> { impl Drop for Context<'_> { fn drop(&mut self) { - unsafe { LLVMContextDispose(self.inner) } + if !self.borrowed { + unsafe { LLVMContextDispose(self.inner) } + } } } diff --git a/src/Rust/vvs_llvm/src/bindings/function.rs b/src/Rust/vvs_llvm/src/bindings/function.rs index 816d13eb..b12f0cca 100644 --- a/src/Rust/vvs_llvm/src/bindings/function.rs +++ b/src/Rust/vvs_llvm/src/bindings/function.rs @@ -63,7 +63,7 @@ impl<'a> Function<'a> { /// Get the LLVM context of the function. pub fn context(&'a self) -> Context<'a> { - unsafe { Context::from_ptr(LLVMGetTypeContext(LLVMTypeOf(self.inner))) } + unsafe { Context::from_ptr(LLVMGetTypeContext(LLVMTypeOf(self.inner)), true) } } /// Add a new basic block to the function and returns it. diff --git a/src/Rust/vvs_llvm/src/bindings/module.rs b/src/Rust/vvs_llvm/src/bindings/module.rs index b11a16c5..4b0f4c32 100644 --- a/src/Rust/vvs_llvm/src/bindings/module.rs +++ b/src/Rust/vvs_llvm/src/bindings/module.rs @@ -27,6 +27,16 @@ impl Module<'_> { ptr => Ok(unsafe { FunctionDeclaration::from_ptr(ptr) }), } } + + /// Get the name of the module. + pub fn name(&self) -> &str { + let mut len = 0; + std::str::from_utf8(unsafe { + let c_ptr = LLVMGetModuleIdentifier(self.as_ptr(), &mut len); + std::slice::from_raw_parts(c_ptr as *const _, len) + }) + .expect("valid utf8 module name") + } } impl Drop for Module<'_> { diff --git a/src/Rust/vvs_llvm/src/init.rs b/src/Rust/vvs_llvm/src/init.rs index dfff4b9a..56355ac9 100644 --- a/src/Rust/vvs_llvm/src/init.rs +++ b/src/Rust/vvs_llvm/src/init.rs @@ -28,7 +28,13 @@ pub fn initialize_llvm() -> anyhow::Result<()> { call_once() .then(|| unsafe { llvm_sys::target::LLVMInitializeX86Target(); + llvm_sys::target::LLVMInitializeX86AsmParser(); + llvm_sys::target::LLVMInitializeX86AsmPrinter(); + llvm_sys::target::LLVMInitializeX86TargetInfo(); + llvm_sys::target::LLVMInitializeX86TargetMC(); + llvm_sys::target::LLVMInitializeX86Disassembler(); print_llvm_infos(); + log::debug!("llvm initialized for target x86_64"); }) .ok_or_else(|| anyhow!("llvm was already initialized for this executable!")) } diff --git a/src/Rust/vvs_runtime/src/jit.rs b/src/Rust/vvs_runtime/src/jit.rs index df58f4b6..e238daed 100644 --- a/src/Rust/vvs_runtime/src/jit.rs +++ b/src/Rust/vvs_runtime/src/jit.rs @@ -72,13 +72,7 @@ impl JIT { unsafe { // Create the jit. let mut jit = ptr::null_mut(); - let mut tmb = ptr::null_mut(); - llvm_expect!(LLVMOrcJITTargetMachineBuilderDetectHost(&mut tmb), "failed to create orc jit builder"); - - let jit_builder = LLVMOrcCreateLLJITBuilder(); - LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(jit_builder, tmb); - llvm_expect!(LLVMOrcCreateLLJIT(&mut jit, jit_builder), "failed to create the orc jit"); - + llvm_expect!(LLVMOrcCreateLLJIT(&mut jit, ptr::null_mut()), "failed to create the orc jit"); log::debug!("got data layout: {}", CStr::from_ptr(LLVMOrcLLJITGetDataLayoutStr(jit)).to_string_lossy()); // Create things, in this order. @@ -116,11 +110,12 @@ impl JIT { /// Get the context out of the JIT thingy. Used to create a LLVM module to be used latter by /// the JIT. pub fn ctx(&self) -> Context { - unsafe { Context::from_ptr(LLVMOrcThreadSafeContextGetContext(self.tsctx)) } + unsafe { Context::from_ptr(LLVMOrcThreadSafeContextGetContext(self.tsctx), true) } } /// Add a new module to the JIT engine. pub fn with_module(&self, module: Module) -> anyhow::Result<&Self> { + log::debug!("add module `{}` to jit engine", module.name()); let tsm = unsafe { LLVMOrcCreateNewThreadSafeModule(module.as_ptr(), self.tsctx) }; let rc = unsafe { LLVMOrcLLJITAddLLVMIRModule(self.jit, self.dylib, tsm) }; unsafe { llvm_expect!(rc, "failed to add the module into the jit") }; diff --git a/src/Rust/vvs_utils/src/rand.rs b/src/Rust/vvs_utils/src/rand.rs index 8b10f723..c49c4aee 100644 --- a/src/Rust/vvs_utils/src/rand.rs +++ b/src/Rust/vvs_utils/src/rand.rs @@ -5,7 +5,7 @@ use std::{cell::RefCell, sync::OnceLock}; /// Simple Mersenne Twister (MT19937-64) implementation. struct MersenneTwister { - mt: [u64; MersenneTwister::W as usize], + mt: [u64; MersenneTwister::N as usize], index: usize, } @@ -77,7 +77,7 @@ pub fn rand() -> u64 { MERSENNE.with(|mt| { mt.get_or_init(|| { let index = MersenneTwister::N as usize; - let mut mt = [0; MersenneTwister::W as usize]; + let mut mt = [0; MersenneTwister::N as usize]; mt[0] = get_seed(); (1..MersenneTwister::N).for_each(|i| { let index = i as usize - 1; diff --git a/src/Rust/vvs_xdg/src/file/lock.rs b/src/Rust/vvs_xdg/src/file/lock.rs index 4c563bcb..4c0fe27f 100644 --- a/src/Rust/vvs_xdg/src/file/lock.rs +++ b/src/Rust/vvs_xdg/src/file/lock.rs @@ -1,7 +1,7 @@ use crate::*; use std::{ collections::hash_map::DefaultHasher, - fs::{File, OpenOptions}, + fs::{self, File, OpenOptions}, hash::{Hash, Hasher}, io::Error as IoError, path::Path, @@ -25,7 +25,9 @@ pub enum LockError { pub type LockResult<T> = Result<T, LockError>; /// Structure used to hold the lock file for a resource that can be hashed. -pub struct LockFile(File); +pub struct LockFile { + path: PathBuf, +} impl LockFile { #[inline] @@ -51,12 +53,14 @@ impl LockFile { .map_err(Self::handle_xdg_error)? { MaybeFolderList::Empty => unreachable!("failed to find the runtime dir..."), - MaybeFolderList::Folder(f) | MaybeFolderList::Many(f, _) => Ok(Self( - OpenOptions::new() + MaybeFolderList::Folder(path) | MaybeFolderList::Many(path, _) => { + log::debug!("create lock file at: {}", path.display()); + let _ = OpenOptions::new() .create_new(true) - .open(f) - .map_err(Self::handle_io_error)?, - )), + .open(&path) + .map_err(Self::handle_io_error)?; + Ok(Self { path }) + } } } @@ -86,6 +90,9 @@ impl LockFile { impl Drop for LockFile { #[inline] fn drop(&mut self) { - todo!("drop {:?}", self.0) + match fs::remove_file(&self.path) { + Ok(_) => log::debug!("remove lock file: {}", self.path.display()), + Err(err) => log::error!("failed to remove lock file '{}': {err}", self.path.display()), + } } } diff --git a/src/Rust/vvs_xdg/src/file/temp.rs b/src/Rust/vvs_xdg/src/file/temp.rs index dc0d36a6..514d496f 100644 --- a/src/Rust/vvs_xdg/src/file/temp.rs +++ b/src/Rust/vvs_xdg/src/file/temp.rs @@ -121,6 +121,7 @@ impl TempFile { pub fn new(app: impl AsRef<str>) -> TempResult<Self> { let (pid, rand) = (std::process::id(), rand()); let path = Self::create(app, format!("tmp.{pid}.{rand}"))?; + log::debug!("create temporary file at: {}", path.display()); let file = OpenOptions::new() .create_new(true) .write(true) -- GitLab