node-pty icon indicating copy to clipboard operation
node-pty copied to clipboard

freeze when using debugger on windows

Open colmaengus opened this issue 8 months ago • 2 comments
trafficstars

I'm seeing a problem where spawn freezes when using the node.js debugger under windows. Without the debugger it works just fine. I've tested using 1.0.0 and v1.1.0-beta30 and the behavior is the same.

I have been using @cdktf/node-pty-prebuilt-multiarch:0.10.1-pre.11 until now and it was working fine. However I need to switch to a later version of node.js and these pre-builds don't work with node.js 23. I've also tried @lydell/node-pty: 1.1.0 but the behavior is the same as the upstream node.pty.

This is the sample code I'm using. I'm using WebStorm for debugging.

const pty = require('node-pty');
const cmd = 'cmd.exe';
const args = [];
const options = {
  name: 'xterm-256color',
  cols: 80,
  rows: 30
};
console.log('before spawn');
const ptyProcess = pty.spawn(cmd, args, options);
console.log('after spawn');
ptyProcess.on('data', (data) => {
  process.stdout.write(data);
});

colmaengus avatar Feb 24 '25 12:02 colmaengus

Same.

Previous versions (before 1.0.0) work fine.

Works find on MacOS.

Hangs on WindowsOS when debugging in WebStorm.

scubadrew-cloudcmd avatar Feb 25 '25 03:02 scubadrew-cloudcmd

Same, process hangs when process tries to spawn on Windows when app is launched in VSCode debugger or in electron

xcariba avatar May 18 '25 18:05 xcariba

@colmaengus are you using a jetbrains IDE?

ScubaDrew avatar Jul 22 '25 03:07 ScubaDrew

Yes, I’m using WebStorm.

On Tue 22 Jul 2025 at 04:12, Drew @.***> wrote:

ScubaDrew left a comment (microsoft/node-pty#763) https://github.com/microsoft/node-pty/issues/763#issuecomment-3100641112

@colmaengus https://github.com/colmaengus are you using a jetbrains IDE?

— Reply to this email directly, view it on GitHub https://github.com/microsoft/node-pty/issues/763#issuecomment-3100641112, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQQORFAGOH3F644JP6H4LD3JWTZVAVCNFSM6AAAAABXX4FYHKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTCMBQGY2DCMJRGI . You are receiving this because you were mentioned.Message ID: @.***>

colmaengus avatar Jul 22 '25 03:07 colmaengus

@colmaengus thought for a moment it might be the jetbrains debugger, but turns out this affects all windows IDEs.

From AI - have not had time to validate:

When a process is being debugged—especially on Windows with Visual Studio Code or other debuggers—it often attaches to the process by opening various handles (think: file descriptors) to its standard streams, threads, memory, and child processes. Here’s why this causes deadlocks when that process spawns another and node-pty is involved:

🕵️‍♂️ What’s happening behind the scenes? 1. Debugger attaches to child processes too When your debugged app does something like child_process.spawn(), the debugger typically attaches to the new child process before it’s allowed to run freely. 2. Handles are left open by the debugger These debugging tools hold on to pipes, STDIN/STDOUT, handles to the new process—often for breakpoint control, I/O capture, or stepping. 3. node-pty tries to hijack the same handles node-pty.spawn() or pty.spawn() wants exclusive control over the terminal’s handles (master/slave ends, pipes). This is necessary to connect the pty ends and shuttle data back and forth. 4. Handle contention arises Because the debugger still holds open one or more of these critical handles, node-pty can’t take ownership or connect properly. The result? Some pipes never get connected or data flows break. 5. The system blocks—deadlock ensues Node-pty waits for an operation (e.g., reading/writing / connecting pipes) that will never complete, since the debugger hasn’t released the handle. So both parties are stuck: the child waits, the pty waits, and nothing progresses.

Real-world workaround

A well-known fix is to disable the Windows ConPTY interface when running under a debugger. ConPTY is the newer Windows pseudoterminal API—and it’s more sensitive to handle conflicts. Typical code workaround:

const useConpty = inspector.url() ? false : undefined;
pty.spawn(shell, args, { useConpty, ... });

This tells node-pty to fall back to the older WinPTY engine, which is inherently more resilient when handles are locked by a debugger—avoiding the deadlock altogether.

ScubaDrew avatar Jul 22 '25 04:07 ScubaDrew