Handle dynamic program dlopen failures gracefully
This commit is contained in:
parent
3828eda507
commit
2d0f07091d
|
@ -13,6 +13,7 @@ use libc;
|
||||||
use libloading::os::unix::*;
|
use libloading::os::unix::*;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use libloading::os::windows::*;
|
use libloading::os::windows::*;
|
||||||
|
use result::Result;
|
||||||
|
|
||||||
use solana_program_interface::account::KeyedAccount;
|
use solana_program_interface::account::KeyedAccount;
|
||||||
use solana_program_interface::pubkey::Pubkey;
|
use solana_program_interface::pubkey::Pubkey;
|
||||||
|
@ -80,12 +81,12 @@ pub enum DynamicProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicProgram {
|
impl DynamicProgram {
|
||||||
pub fn new_native(name: String) -> Self {
|
pub fn new_native(name: String) -> Result<Self> {
|
||||||
// create native program
|
// create native program
|
||||||
let path = ProgramPath::Native {}.create(&name);
|
let path = ProgramPath::Native {}.create(&name);
|
||||||
// TODO linux tls bug can cause crash on dlclose, workaround by never unloading
|
// TODO linux tls bug can cause crash on dlclose, workaround by never unloading
|
||||||
let library = Library::open(Some(path), libc::RTLD_NODELETE | libc::RTLD_NOW).unwrap();
|
let library = Library::open(Some(path), libc::RTLD_NODELETE | libc::RTLD_NOW)?;
|
||||||
DynamicProgram::Native { name, library }
|
Ok(DynamicProgram::Native { name, library })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_bpf_from_file(name: String) -> Self {
|
pub fn new_bpf_from_file(name: String) -> Self {
|
||||||
|
|
|
@ -102,7 +102,13 @@ impl SystemProgram {
|
||||||
}
|
}
|
||||||
SystemProgram::Load { program_id, name } => {
|
SystemProgram::Load { program_id, name } => {
|
||||||
let mut hashmap = loaded_programs.write().unwrap();
|
let mut hashmap = loaded_programs.write().unwrap();
|
||||||
hashmap.insert(program_id, DynamicProgram::new_native(name));
|
hashmap.insert(
|
||||||
|
program_id,
|
||||||
|
DynamicProgram::new_native(name).map_err(|err| {
|
||||||
|
warn!("SystemProgram::Load failure: {:?}", err);
|
||||||
|
Error::InvalidArgument
|
||||||
|
})?,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -142,7 +142,7 @@ fn test_native_file_noop() {
|
||||||
.map(|(key, account)| KeyedAccount { key, account })
|
.map(|(key, account)| KeyedAccount { key, account })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let dp = DynamicProgram::new_native("noop".to_string());
|
let dp = DynamicProgram::new_native("noop".to_string()).unwrap();
|
||||||
dp.call(&mut infos, &data);
|
dp.call(&mut infos, &data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ fn test_native_file_move_funds_success() {
|
||||||
.map(|(key, account)| KeyedAccount { key, account })
|
.map(|(key, account)| KeyedAccount { key, account })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let dp = DynamicProgram::new_native("move_funds".to_string());
|
let dp = DynamicProgram::new_native("move_funds".to_string()).unwrap();
|
||||||
dp.call(&mut infos, &data);
|
dp.call(&mut infos, &data);
|
||||||
}
|
}
|
||||||
assert_eq!(0, accounts[0].tokens);
|
assert_eq!(0, accounts[0].tokens);
|
||||||
|
@ -186,7 +186,7 @@ fn test_native_file_move_funds_insufficient_funds() {
|
||||||
.map(|(key, account)| KeyedAccount { key, account })
|
.map(|(key, account)| KeyedAccount { key, account })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let dp = DynamicProgram::new_native("move_funds".to_string());
|
let dp = DynamicProgram::new_native("move_funds".to_string()).unwrap();
|
||||||
dp.call(&mut infos, &data);
|
dp.call(&mut infos, &data);
|
||||||
}
|
}
|
||||||
assert_eq!(10, accounts[0].tokens);
|
assert_eq!(10, accounts[0].tokens);
|
||||||
|
@ -216,7 +216,7 @@ fn test_program_native_move_funds_succes_many_threads() {
|
||||||
.map(|(key, account)| KeyedAccount { key, account })
|
.map(|(key, account)| KeyedAccount { key, account })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let dp = DynamicProgram::new_native("move_funds".to_string());
|
let dp = DynamicProgram::new_native("move_funds".to_string()).unwrap();
|
||||||
dp.call(&mut infos, &data);
|
dp.call(&mut infos, &data);
|
||||||
}
|
}
|
||||||
assert_eq!(0, accounts[0].tokens);
|
assert_eq!(0, accounts[0].tokens);
|
||||||
|
|
Loading…
Reference in New Issue