diff --git a/src/api/environment.cc b/src/api/environment.cc index a3090f3bf722ac..fa91ed8b404af4 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -714,6 +714,7 @@ ThreadId AllocateEnvironmentThreadId() { void DefaultProcessExitHandler(Environment* env, int exit_code) { Stop(env); 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 00000000000000..a9a70c39e095a3 --- /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));