emscripten-core / emscripten-core/emscripten

Add a graceful version of dlopen()?

Open
#16,790 12 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Attempting to update to Emscripten 3.1.8 from Emscripten 2.0.19, I find an issue with a refactoring that happened in `dlopen()`.

Currently when building without dynamic linking enabled, Emscripten aborts execution altogether if one calls `dlopen()`. C# VMs use dynamic library loading as an internal symbol resolution mechanism, and we used to have this following library override to `dlopen`, which would not abort execution, but instead would gracefully warn and proceed without crashing. (This would result in a cooperative C# exception being thrown, which a lot of C# developers do readily have code to handle already - and issue error messages of their own, or do something else)

```c
mergeInto(LibraryManager.library, {
#if !MAIN_MODULE
#if !SIDE_MODULE
// Stub over core Emscripten dlopen/dlclose behavior to avoid crashing on attempting to dlopen a library.
dlopen__deps: [],
dlopen__proxy: 'async',
dlopen__sig: 'iii',
dlopen: function(filename, flag) {
#if ASSERTIONS
warnOnce('Unable to open DLL ' + UTF8ToString(filename) + '! Dynamic linking is not supported in WebAssembly builds due to limitations to performance and code size. Please statically link in the needed libraries.');
#endif
// Do not abort here - IL2CPP will throw a managed exception.
},

dlclose__deps: [],
dlclose__proxy: 'async',
dlclose__sig: 'ii',
dlclose: function(handle) {
// no-op
},

dlsym__deps: [],
dlsym__proxy: 'async',
dlsym__sig: 'iii',
dlsym: function(handle, symbol) {
return 0;
},

dlerror__deps: [],
dlerror__proxy: 'async',
dlerror__sig: 'i',
dlerror: function() {
return 0;
}
#endif
#endif
});
```

Now with Emscripten 3.1.8, I find that dlopen has been moved to dynlink.c, which implements a different API altogether where `_dlopen_js` should never return false, or execution will abort.

I need to fork dynlink.c for Unity use to avoid the hard abort in this kind of scenario, but I am wondering whether that behavior might just make more sense to be the actual behavior in general? Would it be possible to make stub `dlopen()` not abort?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.