Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deadlock with worker threads and TLS createSecureContext #52698

Open
abrenneke opened this issue Apr 26, 2024 · 2 comments
Open

Deadlock with worker threads and TLS createSecureContext #52698

abrenneke opened this issue Apr 26, 2024 · 2 comments
Labels
openssl Issues and PRs related to the OpenSSL dependency. tls Issues and PRs related to the tls subsystem. worker Issues and PRs related to Worker support.

Comments

@abrenneke
Copy link

abrenneke commented Apr 26, 2024

Version

  • v20.11.0
  • v21.7.3

Platform

Darwin IRONCLADHQ-NMXQRHY6C 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64

Subsystem

crypto?

What steps will reproduce the bug?

I believe the following script reproduces the deadlock:

const { Worker, isMainThread } = require('worker_threads');
const { createSecureContext } = require('tls');

if (isMainThread) {
    for (let i = 0; i < 1000; i++) {
        new Worker(__filename);
    }

    let i = 0;

    const go = () => {
        createSecureContext();
        if (i % 1000 === 0) {
            console.log(i);
        }
        i++;
        setImmediate(go);
    }

    go();
} else {
    const go = () => {
        createSecureContext();
        setImmediate(go);
    }

    go();
}

Here is what I get when running the script:

% node index.js                               
0
1000
2000
3000
4000
5000
6000
^C%                                                                                                                                                           
% node index.js
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
^C%                                                                                                                                                           
% node index.js
0
1000
2000
3000
4000
5000
6000
7000

Here is what the Mac OS process sample shows:

image

Attached here is the full sample for the above process
deadlock.txt

How often does it reproduce? Is there a required condition?

The above script seems to reliably reproduce for me. This may be specific to apple silicon, I'm not sure!

What is the expected behavior? Why is that the expected behavior?

I would expect the above script to run infinitely, and print incrementing values of 1000.

What do you see instead?

The above script freezes after 6-10,000 iterations of the main process. All threads end up deadlocked somehow.

Additional information

This is happening in a production application for us that only has 2 worker threads, it takes as little as 20 minutes, so I'm not sure how it's actually happening to us, but the above script forces the problem. Nobody would create this many secure contexts in practice, probably.

@RedYetiDev RedYetiDev added tls Issues and PRs related to the tls subsystem. worker Issues and PRs related to Worker support. labels Apr 26, 2024
@juanarbol
Copy link
Member

Looking at the codebase, all those locks are managed by OpenSSL; do you think you could create a repro case using OpenSSL stand-alone? If the issue persists; this is probably an OpenSSL issue instead

@juanarbol juanarbol added the openssl Issues and PRs related to the OpenSSL dependency. label May 2, 2024
@abrenneke
Copy link
Author

Sure but I'm not sure how I'd start to approach doing that @juanarbol any suggestions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
openssl Issues and PRs related to the OpenSSL dependency. tls Issues and PRs related to the tls subsystem. worker Issues and PRs related to Worker support.
Projects
None yet
Development

No branches or pull requests

3 participants