Rust: Segfault при выполнении определенной строки кода из динамически загружаемой библиотеки
Я пишу простую систему на основе плагинов в Rust, чтобы получить некоторые навыки и опыт использования языка. Моя система динамически загружает библиотеки и выполняет их во время выполнения для инициализации каждого плагина. Я сталкиваюсь с интересной проблемой segfault при выполнении кода из динамически загружаемой библиотеки.
Это код для загрузки и запуска функции инициализации плагина: (этот бит работает нормально)
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);
}
Это функция init в библиотеке плагинов:
#[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.");
}
Как уже отмечалось, segfault происходит в функции register_plugin структуры PluginSystem с именем ps. Эта структура заимствована из вызывающего метода (в первом фрагменте кода).
Это функция register_plugin в 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);
};
}
Segfault происходит при выполненииHashMap::new()
в этом блоке кода;
Я попытался реализовать эту функцию по-другому, как в:
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) => { }
}
}
Но я получаю точно такую же проблему.
Если я пропускаю функцию register_plugin и запускаю другой код в динамически загружаемой библиотеке, он работает нормально. На самом деле единственный код, на котором этот segfaults являетсяHashMap::new()
.
Это ошибка или существующая проблема, или я делаю что-то не так?
Больше информации: я скомпилировал ржавчину с отладочными символами, чтобы пройтись по коду HashMap, чтобы найти проблему. Похоже, что он даже не пытается выполнить функцию new (), при отладке кода, при входе вHashMap::new()
отладчик переходит непосредственно к этой функции в 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())
};
Сегфо происходит вcause.take()
функция, я думаю, это потому, что my_ep.cause пусто или недоступно. Так что-то генерирует недопустимое исключение, иtry
функция задыхается от этого и дает segfault. Это связано с вызовом кода HashMap из динамически загружаемой библиотеки, но я не знаю, как это связано.
Спасибо за любую помощь.
РЕДАКТИРОВАТЬ: Моя платформа Linux x64, я использую недавно построенную ржавчину от Git Master по состоянию на вчера (28 октября '14).