Skip to content

Commit a60056d

Browse files
committedDec 13, 2014
src: fix addon loader regression
Fix a regression that was introduced in commit a38b917 by removing the bad check. Also rearrange the addon loading logic to ensure that the list of pending addons remains in a consistent state when the shared object fails to load; in particular, when an addon self-registers first, then hits a dynamic linker error in a later constructor. Fixes the following asserting when loading a .node shared object: node: ../src/node.cc:1944: void node::node_module_register(void*): Assertion `(modpending) != (nullptr)' failed. Fixes strongloop/strongops#233. PR-URL: #154 Reviewed-By: Ryan Graham <[email protected]>
1 parent 370e821 commit a60056d

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed
 

‎src/node.cc

+12-15
Original file line numberDiff line numberDiff line change
@@ -1939,9 +1939,6 @@ extern "C" void node_module_register(void* m) {
19391939
mp->nm_link = modlist_linked;
19401940
modlist_linked = mp;
19411941
} else {
1942-
// Once node::Init was called we can only register dynamic modules.
1943-
// See DLOpen.
1944-
CHECK_NE(modpending, nullptr);
19451942
modpending = mp;
19461943
}
19471944
}
@@ -1980,21 +1977,26 @@ typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
19801977
// cache that's a plain C list or hash table that's shared across contexts?
19811978
void DLOpen(const FunctionCallbackInfo<Value>& args) {
19821979
Environment* env = Environment::GetCurrent(args);
1983-
struct node_module* mp;
19841980
uv_lib_t lib;
19851981

1982+
CHECK_EQ(modpending, nullptr);
1983+
19861984
if (args.Length() < 2) {
19871985
env->ThrowError("process.dlopen takes exactly 2 arguments.");
19881986
return;
19891987
}
19901988

19911989
Local<Object> module = args[0]->ToObject(); // Cast
19921990
node::Utf8Value filename(args[1]); // Cast
1991+
const bool is_dlopen_error = uv_dlopen(*filename, &lib);
19931992

1994-
Local<String> exports_string = env->exports_string();
1995-
Local<Object> exports = module->Get(exports_string)->ToObject();
1993+
// Objects containing v14 or later modules will have registered themselves
1994+
// on the pending list. Activate all of them now. At present, only one
1995+
// module per object is supported.
1996+
node_module* const mp = modpending;
1997+
modpending = nullptr;
19961998

1997-
if (uv_dlopen(*filename, &lib)) {
1999+
if (is_dlopen_error) {
19982000
Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
19992001
#ifdef _WIN32
20002002
// Windows needs to add the filename into the error message
@@ -2004,14 +2006,6 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
20042006
return;
20052007
}
20062008

2007-
/*
2008-
* Objects containing v14 or later modules will have registered themselves
2009-
* on the pending list. Activate all of them now. At present, only one
2010-
* module per object is supported.
2011-
*/
2012-
mp = modpending;
2013-
modpending = nullptr;
2014-
20152009
if (mp == nullptr) {
20162010
env->ThrowError("Module did not self-register.");
20172011
return;
@@ -2034,6 +2028,9 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
20342028
mp->nm_link = modlist_addon;
20352029
modlist_addon = mp;
20362030

2031+
Local<String> exports_string = env->exports_string();
2032+
Local<Object> exports = module->Get(exports_string)->ToObject();
2033+
20372034
if (mp->nm_context_register_func != nullptr) {
20382035
mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
20392036
} else if (mp->nm_register_func != nullptr) {

0 commit comments

Comments
 (0)
Please sign in to comment.