gpt4 book ai didi

segmentation-fault - Rust:从动态加载的库执行特定代码行时出现段错误

转载 作者:行者123 更新时间:2023-11-29 07:51:37 29 4
gpt4 key购买 nike

我正在用 Rust 编写一个简单的基于插件的系统,以获取一些使用该语言的技能和经验。我的系统动态加载库并在运行时执行它们以初始化每个插件。从动态加载的库执行代码时,我遇到了一个有趣的段错误问题。

这是加载和运行插件初始化函数的代码:(这部分工作正常)

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);
}

这是插件库中的初始化函数:

#[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.");
}

如评论所述,段错误发生在名为 ps 的 PluginSystem 结构的 register_plugin 函数中。该结构是从调用方法(在第一个代码块中)借用的。

这是 PluginSystem 中的 register_plugin 函数:

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);
};
}

在这段代码块中执行HashMap::new()时出现segfault;

我尝试过以不同的方式实现此功能,例如:

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 函数,并运行动态加载库中的其他代码,它工作正常。事实上,此段错误的唯一代码是 HashMap::new()

这是错误还是现有问题,还是我做错了什么?

更多信息:我用调试符号编译了 rust,以便通过 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()函数中出现了Segfault,我认为是因为my_ep.cause为null或者不可访问。所以某些东西正在生成一个无效的异常,并且 try 函数正在阻塞它并给出段错误。这个和调用动态加载库的HashMap代码有关,不知道是什么关系。

感谢您的帮助。

编辑:我的平台是 linux x64,截至昨天(2014 年 10 月 28 日),我正在使用 git master 新构建的 rust。

最佳答案

我在 GitHub 上提出了一个关于这个的问题 (here),用了一个最小的测试用例,并在几个小时内解决了。

基本上,这是因为 rustc 默认在构建可执行文件时静态链接 libstd,而在构建库时动态链接。所以 main 使用静态 libstd,而在运行时加载 plugin.so 时,插件使用动态 libstd。之后会发生奇怪的内存问题。

通过将 -C prefer-dynamic 添加到主要可执行文件的 rustc 来修复。

关于segmentation-fault - Rust:从动态加载的库执行特定代码行时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26602353/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com