mirror of
https://github.com/electron/electron.git
synced 2026-01-08 23:18:06 -05:00
fix: launch crash when null device is disabled on Windows (#47870)
fix: fix launch crash when null device is disabled on Windows add node flag node::ProcessInitializationFlags::kNoStdioInitialization Co-authored-by: yangzuohui <yangzuohui@bytedance.com> Co-authored-by: yangliu <yangliu.leo@bytedance.com>
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
#include "shell/common/node_bindings.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/node_util.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/platform_util.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "chrome/child/v8_crashpad_support_win.h"
|
||||
@@ -153,9 +155,10 @@ int NodeMain() {
|
||||
v8_crashpad_support::SetUp();
|
||||
#endif
|
||||
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
int pid = -1;
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::optional<std::string> fd_string = os_env->GetVar("CRASHDUMP_SIGNAL_FD");
|
||||
std::optional<std::string> pid_string =
|
||||
os_env->GetVar("CRASHPAD_HANDLER_PID");
|
||||
@@ -189,14 +192,32 @@ int NodeMain() {
|
||||
NodeBindings::RegisterBuiltinBindings();
|
||||
|
||||
// Parse Node.js cli flags and strip out disallowed options.
|
||||
const std::vector<std::string> args = ElectronCommandLine::AsUtf8();
|
||||
std::vector<std::string> args = ElectronCommandLine::AsUtf8();
|
||||
ExitIfContainsDisallowedFlags(args);
|
||||
|
||||
uint64_t process_flags =
|
||||
node::ProcessInitializationFlags::kNoInitializeV8 |
|
||||
node::ProcessInitializationFlags::kNoInitializeNodeV8Platform;
|
||||
|
||||
if (command_line->HasSwitch(switches::kNoStdioInit)) {
|
||||
process_flags |= node::ProcessInitializationFlags::kNoStdioInitialization;
|
||||
// remove the option to avoid node error "bad option: --no-stdio-init"
|
||||
std::string option = std::string("--") + switches::kNoStdioInit;
|
||||
std::erase(args, option);
|
||||
} else {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
if (!platform_util::IsNulDeviceEnabled()) {
|
||||
LOG(FATAL) << "Unable to open nul device needed for initialization,"
|
||||
"aborting startup. As a workaround, try starting with --"
|
||||
<< switches::kNoStdioInit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::shared_ptr<node::InitializationResult> result =
|
||||
node::InitializeOncePerProcess(
|
||||
args,
|
||||
{node::ProcessInitializationFlags::kNoInitializeV8,
|
||||
node::ProcessInitializationFlags::kNoInitializeNodeV8Platform});
|
||||
args, static_cast<node::ProcessInitializationFlags::Flags>(
|
||||
process_flags));
|
||||
|
||||
for (const std::string& error : result->errors())
|
||||
std::cerr << args[0] << ": " << error << '\n';
|
||||
|
||||
@@ -132,6 +132,7 @@ UtilityProcessWrapper::UtilityProcessWrapper(
|
||||
OPEN_EXISTING, 0, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
PLOG(ERROR) << "Failed to create null handle";
|
||||
Emit("error", "Failed to create null handle for ignoring stdio");
|
||||
return;
|
||||
}
|
||||
if (io_handle == IOHandle::STDOUT) {
|
||||
|
||||
@@ -549,7 +549,7 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
|
||||
if (process_type == ::switches::kUtilityProcess ||
|
||||
process_type == ::switches::kRendererProcess) {
|
||||
// Copy following switches to child process.
|
||||
static constexpr std::array<const char*, 9U> kCommonSwitchNames = {
|
||||
static constexpr std::array<const char*, 10U> kCommonSwitchNames = {
|
||||
switches::kStandardSchemes.c_str(),
|
||||
switches::kEnableSandbox.c_str(),
|
||||
switches::kSecureSchemes.c_str(),
|
||||
@@ -558,6 +558,7 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
|
||||
switches::kFetchSchemes.c_str(),
|
||||
switches::kServiceWorkerSchemes.c_str(),
|
||||
switches::kStreamingSchemes.c_str(),
|
||||
switches::kNoStdioInit.c_str(),
|
||||
switches::kCodeCacheSchemes.c_str()};
|
||||
command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
|
||||
kCommonSwitchNames);
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "shell/common/mac/main_application_bundle.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/node_util.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/platform_util.h"
|
||||
#include "shell/common/process_util.h"
|
||||
#include "shell/common/world_ids.h"
|
||||
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
|
||||
@@ -672,6 +674,19 @@ void NodeBindings::Initialize(v8::Isolate* const isolate,
|
||||
if (!fuses::IsNodeOptionsEnabled())
|
||||
process_flags |= node::ProcessInitializationFlags::kDisableNodeOptionsEnv;
|
||||
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kNoStdioInit)) {
|
||||
process_flags |= node::ProcessInitializationFlags::kNoStdioInitialization;
|
||||
} else {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
if (!platform_util::IsNulDeviceEnabled()) {
|
||||
LOG(FATAL) << "Unable to open nul device needed for initialization,"
|
||||
"aborting startup. As a workaround, try starting with --"
|
||||
<< switches::kNoStdioInit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::shared_ptr<node::InitializationResult> result =
|
||||
node::InitializeOncePerProcess(
|
||||
args,
|
||||
|
||||
@@ -309,6 +309,10 @@ inline constexpr base::cstring_view kDisableNTLMv2 = "disable-ntlm-v2";
|
||||
inline constexpr base::cstring_view kServiceWorkerPreload =
|
||||
"service-worker-preload";
|
||||
|
||||
// If set, flag node::ProcessInitializationFlags::kNoStdioInitialization would
|
||||
// be set for node initialization.
|
||||
inline constexpr base::cstring_view kNoStdioInit = "no-stdio-init";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -47,6 +47,9 @@ void Beep();
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// SHGetFolderPath calls not covered by Chromium
|
||||
bool GetFolderPath(int key, base::FilePath* result);
|
||||
|
||||
// Check if nul device can be used.
|
||||
bool IsNulDeviceEnabled();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <comdef.h>
|
||||
#include <commdlg.h>
|
||||
#include <dwmapi.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <objbase.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
@@ -450,4 +452,15 @@ void Beep() {
|
||||
MessageBeep(MB_OK);
|
||||
}
|
||||
|
||||
bool IsNulDeviceEnabled() {
|
||||
bool ret = true;
|
||||
int fd = _open("nul", _O_RDWR);
|
||||
if (fd < 0) {
|
||||
ret = false;
|
||||
} else {
|
||||
_close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace platform_util
|
||||
|
||||
Reference in New Issue
Block a user