rust-lang / rust-lang/git2-rs

Runtime loading the library causes unwanted behavior after unload

Open
#786 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
2.1k
Forks
450
Avg merge
11m
Merged PRs (30d)
1

Description

Hi so I used libloading crate to load a plugin for my code that depends on git2
Once a Repository object was created at least once (even if dropped instantly) during the run of the app upon exit the process closes with:

error: process didn't exit successfully: `target\release\cargo-mol.exe --plugins=target/release/mol_git.dll add` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

I've checked and loading and unloading the plugin code with different dependencies and the process behaves fine no errors
*checked with nalgebra and openssl

I'm not sure how to diagnose the problem deeper don't quite have the experience for it

usage

fn on_load(&mut self) {
    self.repo = Repository::open(DEFAULT_PACKAGE_DIR.as_path()).ok();
}

the exit error happens even if dropped instantly

fn on_load(&mut self) {
    drop(Repository::open("."))
}

plugin loading & unloading

impl PluginManager {
  /// # Safety
  ///
  /// This function opens a compiled cdylib and thus should not be called on cdylib that doesn't implement declare_plugin! macro
  pub unsafe fn load<P: AsRef<OsStr>>(&mut self, library_path: P) -> anyhow::Result<()> {
    let library = Rc::new(Library::new(library_path)?);

    let decl = library
      .get::<*mut PluginDeclaration>(b"plugin_declaration\0")?
      .read();

    // version checks to prevent accidental ABI incompatibilities
    if decl.rustc_version != RUSTC_VERSION || decl.core_version != CORE_VERSION {
      return Err(PluginLoadError::IncompatibleVersion.into());
    }

    let mut registrar = PluginRegistrar::new(Rc::clone(&library));

    (decl.register)(&mut registrar);

    self.plugins.extend(registrar.consume());
    self.libraries.push(library);

    Ok(())
  }
}

impl Drop for PluginManager {
  fn drop(&mut self) {
    for mut plugin in self.plugins.drain(..) {
      plugin.on_unload();
    }

    for library in self.libraries.drain(..) {
      drop(library);
    }
  }
}

**checked and Rc for Library is at 1 strong 0 weak before being dropped

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the Windows STATUS_ACCESS_VIOLATION with the linked crates/mol-git/src/lib.rs usage and the plugin load/unload path in crates/mol-core/src/plugin.rs. Trace Repository::open and the library drop sequence to determine whether unloading after libgit2 use is supported; done means the cause and a verified resolution or limitation are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.