diff --git a/src/api/environment.cc b/src/api/environment.cc index a99201e7621..6cd2c6c34a1 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -705,6 +705,7 @@ void DefaultProcessExitHandler(Environment* env, int exit_code) { env->set_can_call_into_js(false); env->stop_sub_worker_contexts(); DisposePlatform(); + uv_library_shutdown(); exit(exit_code); } diff --git a/test/parallel/test-crypto-op-during-process-exit.js b/test/parallel/test-crypto-op-during-process-exit.js new file mode 100644 index 00000000000..a9a70c39e09 --- /dev/null +++ b/test/parallel/test-crypto-op-during-process-exit.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) { common.skip('missing crypto'); } +const assert = require('assert'); +const { generateKeyPair } = require('crypto'); + +if (common.isWindows) { + // Remove this conditional once the libuv change is in Node.js. + common.skip('crashing due to https://github.com/libuv/libuv/pull/2983'); +} + +// Regression test for a race condition: process.exit() might lead to OpenSSL +// cleaning up state from the exit() call via calling its destructor, but +// running OpenSSL operations on another thread might lead to them attempting +// to initialize OpenSSL, leading to a crash. +// This test crashed consistently on x64 Linux on Node v14.9.0. + +generateKeyPair('rsa', { + modulusLength: 2048, + privateKeyEncoding: { + type: 'pkcs1', + format: 'pem' + } +}, (err/* , publicKey, privateKey */) => { + assert.ifError(err); +}); + +setTimeout(() => process.exit(), common.platformTimeout(10));