Native module compilation crashes if create the restify server before the load. Considering the source code example below, if I load the localize module before the restify.createServer() a crash shows up. However, if load the localize after the crash does not happens.
The localize module loads a native module. This native module causes the crash described below
4.0.3
node --version
v4.4.4
Run the script
root@localhost:/usr/share/something# node t.js
crypto.js:50
this._handle = new binding.Hash(algorithm);
^
Error: Digest method not supported
at Error (native)
at new Hash (crypto.js:50:18)
at Object.Hash (crypto.js:49:12)
at getDefaultSessionIdContext (_tls_wrap.js:27:19)
at _tls_wrap.js:17:33
at NativeModule.compile (node.js:959:5)
at NativeModule.require (node.js:904:18)
at tls.js:221:21
at NativeModule.compile (node.js:959:5)
at NativeModule.require (node.js:904:18)
root@nodegrid:/usr/share/webserver#
var restify = require("restify");
var localize = require("./localize");
var server = restify.createServer();
Yes, but I would like a code pointer because I'm read the node.js and restify code but did not find the root cause.
Hey @jvanz!
I think you are the first to use our new issue template :grin:
Thank you for the repro case! I'm having trouble running it locally though, what is providing ./localize, would you mind sharing that file? I'm happy to help debug, and appreciate your willingness to tackle fixing the bug!
Hi @retrohacker !
I'm glad to work with you on that. However, I'm not allow to send you that file, sorry about that. I can tell you that I'm trying to find a repro case with out that module but I could not so far. As far as I can tell reading the node.js and restify code the problem is when a native module is load. The .localize loads a native module and in the compile method the crash is throw. According to the stack trace the problematic module is tls.
But I do not have a clue why this module loading crashes after load restify module and create the server. Take a look in the following script:
var native_module = require('path/to/native/module');
var restify = require("restify");
native_module.someMethod('arg');
var server = restify.createServer();
If I move the native module call to before var restify = require("restify"); or after var server = restify.createServer(); everything go fine. But if I call between these two statements the script crashes.
Interesting!
Would it be possible to chip away at .localize until only a few lines that uncover the bug are left, and share that smaller repro case?
No, It wouldn't. Sorry buddy. I can not open the module. I'm trying to simulate the same problem with a dummy native module, without success.
That is unfortunate. Without a repro case that we can use to replicate the bug, it will be hard to determine whether this is a bug in restify or something localize is doing. Even if we can narrow it down to restify, it is going to be incredibly difficult for anyone to find the bug without being able to see it :disappointed: .
Since you are the only capable of debugging this, I can give you a few pointers to try and narrow this down, but I'm not going to be able to help much beyond that.
First, if you try running this snippet, you can start narrowing down where the error is happening.
console.log('foo');
var restify = require("restify");
console.log('bar');
var localize = require("./localize");
console.log('beep');
var server = restify.createServer();
console.log('bop');
Once you narrow that down, you can further use printf in c++ and console.log in Node to trace your way down through the logic. Might be easier than trying to step through the Node.js/C++ boundary with a debugger. Alternatively, there is llnode for stepping through your code but there is a high learning curve if you aren't used to working on this level.
Have you tried using http and/or https instead of restify to check if the error still happens? Also, you may want to start iteratively commenting out large chunks of ./node_modules/restify to see when the problem goes away. If you can't narrow down what is causing the problem in localize you may be able to narrow down what is happing on restify's side of things.
Wish I could be more help. Good luck! Let us know if you find anything :smile:
I understand and agree with your point. I'll do that, and let you know when I found the problem. Thank you for your help and time! =)
I believe that I found the root cause. The restify.createServer() crashes when the server.js inside restify loads the https. In the https, when tls (require by https) module is loaded it tries create a Hash object and the native code who does that uses a previous initialized OpenSSL context does so. In theory, the node.js module init the context but my native module uses the xmlsec lib which does that too. So, I think the node.js module is using a OpenSSL initialized by xmlsec instead of the using the context initialized by the node.js module.
In summary, I suspected the native code, via xmlsec lib, initializes a OpenSSL context using OpenSSL_add_all_algorithms functions before the tls module and for some reason the node.js module does not check is the context contains all capabilities its expected and the call fail.
Now, I'll try to create a dummy native module using the xmlsec to test this theory. Considering that I do not have so many experience with OpenSSL I can find something else. xD
Woah! Officially l33t h4x0r status, tracing this down to an OpenSSL context in node core is pretty intense.
It sounds like the bug is in the tls module in the Node.js project. Should the conversation move to a new issue over there? I'm still going to subscribe to the new thread, I'm interested in seeing where this leads :smile:
I'll try to create a environment to simulate the issue and then create an issue in the node.js repo. I'll update here to keep everybody informed.
Finally, I got a repro case! :)
https://github.com/nodejs/node/issues/13213
Awesomesauce!
I'm going to close this issue in favor of the Node.js issue. Awesome work on this @jvanz <3
Thank @retrohacker for your time and help! =)