Im writing a simple plugin-based system in Rust to gain some skills and experience using the language. My system dynamically loads libraries and executes them at runtime to initialize each plugin. Im running into an interesting segfault issue when executing code from a dynamically-loaded library.

This is the code to load and run the plugin init function: (this bit works fine)

pub fn register_plugins<'rp>(&'rp mut self) { let p1 = match DynamicLibrary::open(Some("librust_plugin_1.so")) { Ok(lib) => lib, Err(error) => fail!("Could not load the library: {}", error) }; let s1: extern "Rust" fn(&PluginSystem) = unsafe { match p1.symbol("init") { Err(error) => fail!("Could not load function init: {}", error), Ok(init) => mem::transmute::<*mut u8, _>(init) } }; s1(&self.ps); }

This is the init function within the plugin library:

#[no_mangle] pub fn init(ps:&mut PluginSystem) { ps.register_plugin("ps1"); //<-- Segfault is in this method ps.add_new_hook_with_closure("onLoad", "ps1", "display greeting.", 10, test1); println!("Initialized plugin."); }

As commented, the segfault occurs within the register_plugin function of the PluginSystem struct named ps. This struct is borrowed from the calling method (in the first code chunk).

This is the register_plugin function in PluginSystem:

pub fn register_plugin(&mut self, plugin_name: &'s str) { if ! self.plugins.contains_key(&plugin_name) { let hm = HashMap::new(); //<-- Segfault Here self.plugins.insert(plugin_name, hm); }; }

The segfault occurs when executing HashMap::new() in this code block;

I have tried implementing this function differently, as in:

pub fn register_plugin(&mut self, plugin_name: &'s str) { match self.plugins.entry(plugin_name) { Vacant(entry) => { entry.set(HashMap::new()); //<-- Segfault Here } Occupied(mut entry) => { } } }

But I get exactly the same issue.

If I skip the register_plugin function, and run other code in the dynamically-loaded library, it works fine. In fact the only code which this segfaults on is HashMap::new() .

Is this a bug or an existing issue, or am I doing something wrong?

More Info: I compiled rust with debugging symbols in order to step through HashMap code to find the issue. It looks like it doesn't even try to execute the new() function, when debugging the code, when stepping into HashMap::new() the debugger steps directly to this function in unwind.rs:

pub unsafe fn try(f: ||) -> ::core::result::Result<(), Box<Any + Send>> { let closure: Closure = mem::transmute(f); let ep = rust_try(try_fn, closure.code as *mut c_void, closure.env as *mut c_void); return if ep.is_null() { Ok(()) } else { let my_ep = ep as *mut Exception; //<-- Steps into this line rtdebug!("caught {}", (*my_ep).uwe.exception_class); let cause = (*my_ep).cause.take(); //<-- Segfaults Here uw::_Unwind_DeleteException(ep); Err(cause.unwrap()) };

The Segfault occurs in the cause.take() function, I think it is because my_ep.cause is null or inaccessible. So something is generating an invalid exception, and try function is choking on it and giving the segfault. This is related to calling the HashMap code from the dynamically-loaded library, but I don't know how it is related.

Thanks for any help.

EDIT: My platform is linux x64, im using a freshly built rust from git master as of yesterday (28 Oct '14).