Skip to content

Commit 2a97a9b

Browse files
dlopen support for fork and thread (#1037)
* fix dlopen in child process * apply format * fix symbol scope for linker * sync up dlopen-ed libraryes across fork * sync dlopen across thread creation * refactor global snapshots * remove redundent code * clean up * add double fork dlopen test * refactor instance name * add debug panic for same module name * update skip_test_cases.txt * update comment * enforce debug panic on dlopen in multithread * replace module.name().unwrap() with lind_debug_panic
1 parent 7e2038d commit 2a97a9b

File tree

13 files changed

+763
-67
lines changed

13 files changed

+763
-67
lines changed

skip_test_cases.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ signal_tests/deterministic/signal_int_thread.c
33
signal_tests/deterministic/signal_longjmp.c
44
signal_tests/deterministic/signal_nodefer.c
55
memory_tests/deterministic/tcache_test.c
6-
dylink_tests/deterministic/main.c
76
dylink_tests/deterministic/lib.c
7+
dylink_tests/deterministic/basic.c
8+
dylink_tests/deterministic/dlopen_fork.c
9+
dylink_tests/deterministic/dlopen_thread.c
10+
dylink_tests/deterministic/double_fork_dlopen.c
11+
dylink_tests/deterministic/fork_dlopen.c
812
ci/deterministic/ci_intentional_failure_tmp.c
913
concurrent-request/thread_race_grate.c

src/lind-boot/src/lind_wasmtime/execute.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use sysdefs::constants::lind_platform_const::{INSTANCE_NUMBER, RAWPOSIX_CAGEID,
1212
use sysdefs::constants::{
1313
DEFAULT_STACKSIZE, DylinkErrorCode, GUARD_SIZE, LINDFS_ROOT, TABLE_START_INDEX,
1414
};
15+
use sysdefs::logging::lind_debug_panic;
1516
use threei::threei_const;
1617
use wasmtime::{
1718
AsContextMut, Engine, Export, Func, InstantiateType, Linker, Module, Precompiled, SharedMemory,
@@ -231,6 +232,7 @@ pub fn execute_with_lind(
231232
attach_api(
232233
&mut wstore,
233234
&mut linker,
235+
dylink_metadata.got.clone(),
234236
&modules,
235237
lind_manager.clone(),
236238
lind_boot.clone(),
@@ -454,6 +456,7 @@ fn register_wasmtime_syscall_entry() -> bool {
454456
fn attach_api(
455457
wstore: &mut Store<HostCtx>,
456458
mut linker: &mut Arc<Mutex<Linker<HostCtx>>>,
459+
got_table: Option<Arc<Mutex<LindGOT>>>,
457460
modules: &Vec<(String, String, Module)>,
458461
lind_manager: Arc<LindCageManager>,
459462
lindboot_cli: CliOptions,
@@ -464,23 +467,22 @@ fn attach_api(
464467
// (syscall dispatch, debug, signals, and argv/environ) to the linker.
465468
wstore.data_mut().lind_environ = Some(LindEnviron::new(&lindboot_cli.args, &lindboot_cli.vars));
466469

467-
// cloning the reference to the same linker and got
468-
// later when dlopen is invoked, same linker and got instance can be used for instantiate the new library
470+
// Build a dynamic loader closure that reads the current cage's linker and GOT
471+
// at dlopen call time. This ensures the correct per-cage linker is used
472+
// rather than a snapshot captured at cage creation.
469473
let dynamic_loader = {
470474
if dylink_metadata.dylink_enabled {
471-
let cloned_linker = linker.clone();
472-
let lind_got = dylink_metadata.got.as_ref().unwrap();
473-
let cloned_got = lind_got.clone();
474475
let dynamic_loader: DynamicLoader<HostCtx> =
475476
Arc::new(move |caller, cageid, library_name, mode| {
476-
load_library_module(
477-
caller,
478-
cloned_linker.clone(),
479-
cloned_got.clone(),
480-
cageid,
481-
library_name,
482-
mode,
483-
)
477+
let lind_ctx = caller.data().lind_fork_ctx.as_ref().unwrap();
478+
let linker = lind_ctx.linker.clone().unwrap();
479+
let got_table = lind_ctx.got_table.clone().unwrap();
480+
481+
if lind_ctx.had_threads() {
482+
lind_debug_panic("dlopen within threads is currently not supported!");
483+
}
484+
485+
load_library_module(caller, linker, got_table, cageid, library_name, mode)
484486
});
485487
Some(dynamic_loader)
486488
} else {
@@ -508,6 +510,7 @@ fn attach_api(
508510
let _ = wstore.data_mut().lind_fork_ctx = Some(LindCtx::new(
509511
modules.clone(),
510512
linker_guard.clone(),
513+
got_table,
511514
lind_manager.clone(),
512515
lindboot_cli.clone(),
513516
cageid,
@@ -565,6 +568,13 @@ fn load_main_module(
565568
.context(format!("failed to instantiate"))?;
566569
drop(linker);
567570

571+
// Register the main module so get_global_snapshot can find it by name.
572+
if let Some(name) = module.name() {
573+
store
574+
.as_context_mut()
575+
.register_named_instance(name.to_string(), cage_instanceid);
576+
}
577+
568578
// If `_initialize` is present, meaning a reactor, then invoke
569579
// the function.
570580
if let Some(func) = instance.get_func(&mut *store, "_initialize") {
@@ -711,7 +721,7 @@ fn load_main_module(
711721
/// which is used by dlsym symbol lookup
712722
fn load_library_module(
713723
mut main_module: &mut wasmtime::Caller<HostCtx>,
714-
mut main_linker: Arc<Mutex<Linker<HostCtx>>>,
724+
mut linker: Linker<HostCtx>,
715725
mut lind_got: Arc<Mutex<LindGOT>>,
716726
cageid: i32,
717727
library_name: &str,
@@ -758,7 +768,6 @@ fn load_library_module(
758768

759769
// Grow the shared function table to reserve space for this library's
760770
// function entries, as declared in its dylink section.
761-
let mut linker = main_linker.lock().unwrap();
762771
let mut got_guard = lind_got.lock().unwrap();
763772

764773
// Install placeholder GOT globals for this library's imports.
@@ -773,7 +782,7 @@ fn load_library_module(
773782
// the library's function references can be relocated correctly.
774783
//
775784
// The GOT is used to patch symbol addresses/indices after instantiation.
776-
match linker.module_with_caller(
785+
let ret = match linker.module_with_caller(
777786
&mut main_module,
778787
cageid as u64,
779788
library_name,
@@ -789,7 +798,13 @@ fn load_library_module(
789798
println!("failed to process library `{}`", library_name);
790799
-(DylinkErrorCode::EINTERNAL as i32) // consider as internal error for now
791800
}
792-
}
801+
};
802+
803+
let lind_ctx = main_module.data_mut().lind_fork_ctx.as_mut().unwrap();
804+
lind_ctx.attach_linker(linker);
805+
lind_ctx.append_module(library_name.to_string(), lib_module);
806+
807+
ret
793808
}
794809

795810
/// AOT-compile a `.wasm` file to a `.cwasm` artifact on disk.

0 commit comments

Comments
 (0)