Skip to content

fix(compile): panic when compiled with --no-terminal flag #28823

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

Merged
merged 5 commits into from
Apr 29, 2025

Conversation

JasperVanEsveld
Copy link
Contributor

@JasperVanEsveld JasperVanEsveld commented Apr 10, 2025

This works towards fixing #27730 and #21091.

When compiled with the --no-terminal flag under windows there are some issues related to stdin, stdout and stderr.
This pull request fixes the panic when during bootstrap the terminal type is requested.
Previously it would return the error if the terminal was not valid, instead it now returns UNKNOWN.

The dummy stdin that is than provided instantly pushes null for some reason.
However this tries to do a debugLog which is not possible yet, as we are still initiating.
I don't see the use for this push, so I removed the line.
If it is needed for something please let me know.

This PR does not fully fix the issue yet, as there is a similar problem in deno_core's isTerminal op, see this pull request.

ry pushed a commit to denoland/deno_core that referenced this pull request Apr 11, 2025
This works towards fixing
[#27730](denoland/deno#27730) and
[#21091](denoland/deno#21091).

An error is not handled when calling `op_is_terminal`.
Ironically, this causes the application to panic when bootstrapping if
there is no terminal in windows.

This PR does not fully fix the issue yet, as there is a similar problem
in deno's code base, see this [pull
request](denoland/deno#28823).
@JasperVanEsveld
Copy link
Contributor Author

Can some one please review this one? 🙏
@ry merged a related PR in deno-core, if this one is also merged the issues can be closed.

Not sure if/who I should mention to get more eyes on it, or just have patience...

@dsherret dsherret requested a review from littledivy April 16, 2025 17:00
@dsherret dsherret added this to the 2.3.0 milestone Apr 16, 2025
Comment on lines 215 to 218
// deno-lint-ignore prefer-primordials
stdin.push(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change needed? Seems quite risky without any tests attached

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was needed because it used debugLog somewhere in _streams.mjs.
But that is not yet possible because the debug environment is not yet initialized which causes it to panic.
However, I will need to check again if this is needed because #28855 got merged.

I didn't understand what the line was for but looking at the Node API it is supposed to end the stream when you push null. I am not entirely sure if this is needed, stdin is normally not instantly ended.
I don't think it is needed to end the stream for compatibility reasons with Node, as I don't think there is a similar feature for node.

In case the stdin stream does need to end, the push needs to be called after initializeDebugEnv(nodeDebug). To do that you would again have to check that the stream is a dummy stdin.

const newStdin = initStdin();
if (newStdin) {
stdin = process.stdin = newStdin;
}
// Replace stdout/stderr if they are not terminals
if (!io.stdout.isTerminal()) {
/** https://nodejs.org/api/process.html#process_process_stdout */
stdout = process.stdout = createWritableStdioStream(
io.stdout,
"stdout",
);
}
if (!io.stderr.isTerminal()) {
/** https://nodejs.org/api/process.html#process_process_stderr */
stderr = process.stderr = createWritableStdioStream(
io.stderr,
"stderr",
);
}
arch = arch_();
platform = isWindows ? "win32" : Deno.build.os;
pid = Deno.pid;
initializeDebugEnv(nodeDebug);

Let me first check if debugLog is still called

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change related to the issue in this PR? Can we just merge the other change in here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with David, it probably should be added in another PR (if it's needed at all)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was related to the issue before, as this was one of the points where it would panic when running without a terminal.
Just checked and it no longer calls debugLog or at least no longer panics so this is not required anymore! 👍

@bartlomieju bartlomieju self-assigned this Apr 22, 2025
@bartlomieju
Copy link
Member

@JasperVanEsveld thanks for the PR, is there a test we could add that exercises this change?

@JasperVanEsveld
Copy link
Contributor Author

@bartlomieju
A test I can think of is to check if HandleType::Unknown is returned when it uses an OpState that throws an error.
Which should happen if it is given an empty OpState.

I tried to do this but the compiler tells me op_node_guess_handle_type takes 0 arguments.
Is there an easy way to test opcode functions, so functions that use #[op2]?

I tried something like this:

#[cfg(test)]
mod tests {
  use deno_core::OpState;
  use super::*;

  #[test]
  fn guesshandletype_emptystate() {
    let empty_state = OpState::new(None, None);
    let actual = op_node_guess_handle_type(empty_state, 0);
    assert_eq!(actual, HandleType::Unknown);
  }
}

Copy link
Member

@dsherret dsherret left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks!

@dsherret dsherret enabled auto-merge (squash) April 29, 2025 14:55
@dsherret dsherret merged commit 7b28e76 into denoland:main Apr 29, 2025
18 checks passed
@JasperVanEsveld
Copy link
Contributor Author

@bartlomieju @dsherret
I think I accidentally used the wrong executable before, because the new releases still panics.
The stdin.push(null); line still causes a panic, delaying the initialization of stdin until after debug environment is initialized fixes this issue. Meaning that stdin.push(null); does not have to be removed.

#29144 does exactly that.
Please take a look when either of you have the time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants