Bug 1528963 - Attach console before launching child. r=aklotz
☠☠ backed out by 7cfcdf742d19 ☠ ☠
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Thu, 28 Mar 2019 21:37:52 +0000
changeset 466667 7cb86942ed34f38e03e7f2a0eefee0a3141980b5
parent 466666 0ced14667fc51ccf37859cc3b21397fe7ff91e43
child 466668 46b9df4a18e8b174991aff1b44d6bd1442db91d4
push id81739
push useraklotz@mozilla.com
push dateThu, 28 Mar 2019 23:28:43 +0000
treeherderautoland@7cb86942ed34 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1528963
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1528963 - Attach console before launching child. r=aklotz Differential Revision: https://phabricator.services.mozilla.com/D23807
browser/app/winlauncher/LauncherProcessWin.cpp
browser/app/winlauncher/moz.build
toolkit/xre/nsAppRunner.h
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsNativeAppSupportWin.cpp
widget/windows/WindowsConsole.cpp
widget/windows/WindowsConsole.h
widget/windows/moz.build
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/CmdLineAndEnvUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/DynamicallyLinkedFunctionPtr.h"
 #include "mozilla/glue/Debug.h"
 #include "mozilla/LauncherResult.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/SafeMode.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/WindowsConsole.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/WinHeaderOnlyUtils.h"
 #include "nsWindowsHelpers.h"
 
 #include <windows.h>
 #include <processthreadsapi.h>
 
 #include "DllBlocklistWin.h"
@@ -214,16 +215,18 @@ Maybe<int> LauncherMain(int& argc, wchar
       imgLoadPol.PreferSystem32Images = 1;
 
       DebugOnly<BOOL> setOk = pSetProcessMitigationPolicy(
           ProcessImageLoadPolicy, &imgLoadPol, sizeof(imgLoadPol));
       MOZ_ASSERT(setOk);
     }
   }
 
+  mozilla::UseParentConsole();
+
   if (!SetArgv0ToFullBinaryPath(argv)) {
     HandleLauncherError(LAUNCHER_ERROR_GENERIC());
     return Nothing();
   }
 
   LauncherFlags flags = ProcessCmdLine(argc, argv);
 
   nsAutoHandle mediumIlToken;
--- a/browser/app/winlauncher/moz.build
+++ b/browser/app/winlauncher/moz.build
@@ -26,13 +26,14 @@ OS_LIBS += [
 
 TEST_DIRS += [
     'test',
 ]
 
 if CONFIG['MOZ_LAUNCHER_PROCESS']:
     UNIFIED_SOURCES += [
         '/toolkit/xre/LauncherRegistryInfo.cpp',
+        '/widget/windows/WindowsConsole.cpp',
     ]
     for var in ('MOZ_APP_BASENAME', 'MOZ_APP_VENDOR'):
         DEFINES[var] = '"%s"' % CONFIG[var]
 
 DisableStlWrapping()
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAppRunner_h__
 #define nsAppRunner_h__
 
 #ifdef XP_WIN
 #  include <windows.h>
+#  include "mozilla/WindowsConsole.h"
 #else
 #  include <limits.h>
 #endif
 
 #ifndef MAXPATHLEN
 #  ifdef PATH_MAX
 #    define MAXPATHLEN PATH_MAX
 #  elif defined(_MAX_PATH)
@@ -95,17 +96,16 @@ void OverrideDefaultLocaleIfNeeded();
 
 /**
  * Allow exit() calls to complete. This should be done from a proper Gecko
  * shutdown path. Otherwise we aim to catch improper shutdowns.
  */
 void MozExpectedExit();
 
 #ifdef XP_WIN
-void UseParentConsole();
 
 BOOL WinLaunchChild(const wchar_t* exePath, int argc, char** argv,
                     HANDLE userToken = nullptr, HANDLE* hProcess = nullptr);
 
 #  define PREF_WIN_REGISTER_APPLICATION_RESTART \
     "toolkit.winRegisterApplicationRestart"
 
 #  if defined(MOZ_LAUNCHER_PROCESS)
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -75,16 +75,17 @@
 
 #include "mozilla/plugins/PluginProcessChild.h"
 #include "mozilla/dom/ContentProcess.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/XPCShellEnvironment.h"
+#include "mozilla/WindowsConsole.h"
 #include "mozilla/WindowsDllBlocklist.h"
 
 #include "GMPProcessChild.h"
 #include "mozilla/gfx/GPUProcessImpl.h"
 #include "mozilla/net/SocketProcessImpl.h"
 
 #include "GeckoProfiler.h"
 
@@ -376,29 +377,17 @@ nsresult XRE_InitChildProcess(int aArgc,
 
 #if defined(XP_WIN)
   // From the --attach-console support in nsNativeAppSupportWin.cpp, but
   // here we are a content child process, so we always attempt to attach
   // to the parent's (ie, the browser's) console.
   // Try to attach console to the parent process.
   // It will succeed when the parent process is a command line,
   // so that stdio will be displayed in it.
-  if (AttachConsole(ATTACH_PARENT_PROCESS)) {
-    // Change std handles to refer to new console handles.
-    // Before doing so, ensure that stdout/stderr haven't been
-    // redirected to a valid file
-    if (_fileno(stdout) == -1 || _get_osfhandle(fileno(stdout)) == -1)
-      freopen("CONOUT$", "w", stdout);
-    // Merge stderr into CONOUT$ since there isn't any `CONERR$`.
-    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
-    if (_fileno(stderr) == -1 || _get_osfhandle(fileno(stderr)) == -1)
-      freopen("CONOUT$", "w", stderr);
-    if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1)
-      freopen("CONIN$", "r", stdin);
-  }
+  UseParentConsole();
 
 #  if defined(MOZ_SANDBOX)
   if (aChildData->sandboxTargetServices) {
     SandboxTarget::Instance()->SetTargetServices(
         aChildData->sandboxTargetServices);
   }
 #  endif
 #endif
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -1,18 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNativeAppSupportBase.h"
 #include "nsNativeAppSupportWin.h"
 
-#include <windows.h>
-#include <fcntl.h>
+#include "mozilla/WindowsConsole.h"
 
 using namespace mozilla;
 
 /*
  * This code attaches the process to the appropriate console.
  */
 
 class nsNativeAppSupportWin : public nsNativeAppSupportBase {
@@ -21,35 +20,16 @@ class nsNativeAppSupportWin : public nsN
   // option: "--console", which dynamically creates a Windows
   // console.
   void CheckConsole();
 
  private:
   ~nsNativeAppSupportWin() {}
 };  // nsNativeAppSupportWin
 
-void UseParentConsole() {
-  if (AttachConsole(ATTACH_PARENT_PROCESS)) {
-    // Redirect the standard streams to the existing console, but
-    // only if they haven't been redirected to a valid file.
-    // Visual Studio's _fileno() returns -2 for the standard
-    // streams if they aren't associated with an output stream.
-    if (_fileno(stdout) == -2) {
-      freopen("CONOUT$", "w", stdout);
-    }
-    // There is no CONERR$, so use CONOUT$ for stderr as well.
-    if (_fileno(stderr) == -2) {
-      freopen("CONOUT$", "w", stderr);
-    }
-    if (_fileno(stdin) == -2) {
-      freopen("CONIN$", "r", stdin);
-    }
-  }
-}
-
 void nsNativeAppSupportWin::CheckConsole() {
   for (int i = 1; i < gArgc; ++i) {
     if (strcmp("-console", gArgv[i]) == 0 ||
         strcmp("--console", gArgv[i]) == 0 ||
         strcmp("/console", gArgv[i]) == 0) {
       if (AllocConsole()) {
         // Redirect the standard streams to the new console, but
         // only if they haven't been redirected to a valid file.
copy from toolkit/xre/nsNativeAppSupportWin.cpp
copy to widget/windows/WindowsConsole.cpp
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/widget/windows/WindowsConsole.cpp
@@ -1,36 +1,21 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsNativeAppSupportBase.h"
-#include "nsNativeAppSupportWin.h"
+#include "WindowsConsole.h"
 
 #include <windows.h>
 #include <fcntl.h>
 
-using namespace mozilla;
-
-/*
- * This code attaches the process to the appropriate console.
- */
+namespace mozilla {
 
-class nsNativeAppSupportWin : public nsNativeAppSupportBase {
- public:
-  // Utility function to handle a Win32-specific command line
-  // option: "--console", which dynamically creates a Windows
-  // console.
-  void CheckConsole();
-
- private:
-  ~nsNativeAppSupportWin() {}
-};  // nsNativeAppSupportWin
-
+// This code attaches the process to the appropriate console.
 void UseParentConsole() {
   if (AttachConsole(ATTACH_PARENT_PROCESS)) {
     // Redirect the standard streams to the existing console, but
     // only if they haven't been redirected to a valid file.
     // Visual Studio's _fileno() returns -2 for the standard
     // streams if they aren't associated with an output stream.
     if (_fileno(stdout) == -2) {
       freopen("CONOUT$", "w", stdout);
@@ -40,50 +25,9 @@ void UseParentConsole() {
       freopen("CONOUT$", "w", stderr);
     }
     if (_fileno(stdin) == -2) {
       freopen("CONIN$", "r", stdin);
     }
   }
 }
 
-void nsNativeAppSupportWin::CheckConsole() {
-  for (int i = 1; i < gArgc; ++i) {
-    if (strcmp("-console", gArgv[i]) == 0 ||
-        strcmp("--console", gArgv[i]) == 0 ||
-        strcmp("/console", gArgv[i]) == 0) {
-      if (AllocConsole()) {
-        // Redirect the standard streams to the new console, but
-        // only if they haven't been redirected to a valid file.
-        // Visual Studio's _fileno() returns -2 for the standard
-        // streams if they aren't associated with an output stream.
-        if (_fileno(stdout) == -2) {
-          freopen("CONOUT$", "w", stdout);
-        }
-        // There is no CONERR$, so use CONOUT$ for stderr as well.
-        if (_fileno(stderr) == -2) {
-          freopen("CONOUT$", "w", stderr);
-        }
-        if (_fileno(stdin) == -2) {
-          freopen("CONIN$", "r", stdin);
-        }
-      }
-    } else if (strcmp("-attach-console", gArgv[i]) == 0 ||
-               strcmp("--attach-console", gArgv[i]) == 0 ||
-               strcmp("/attach-console", gArgv[i]) == 0) {
-      UseParentConsole();
-    }
-  }
-}
-
-// Create and return an instance of class nsNativeAppSupportWin.
-nsresult NS_CreateNativeAppSupport(nsINativeAppSupport **aResult) {
-  nsNativeAppSupportWin *pNative = new nsNativeAppSupportWin;
-  if (!pNative) return NS_ERROR_OUT_OF_MEMORY;
-
-  // Check for dynamic console creation request.
-  pNative->CheckConsole();
-
-  *aResult = pNative;
-  NS_ADDREF(*aResult);
-
-  return NS_OK;
-}
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/windows/WindowsConsole.h
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_WindowsConsole_h
+#define mozilla_WindowsConsole_h
+
+namespace mozilla {
+
+// This code attaches the process to the appropriate console.
+void UseParentConsole();
+
+}  // namespace mozilla
+
+#endif  // mozilla_WindowsConsole_h
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -14,16 +14,17 @@ TEST_DIRS += ['tests']
 
 EXPORTS += [
     'nsdefs.h',
     'WindowHook.h',
     'WinUtils.h',
 ]
 
 EXPORTS.mozilla += [
+    'WindowsConsole.h',
     'WinHeaderOnlyUtils.h',
 ]
 
 EXPORTS.mozilla.widget += [
     'AudioSession.h',
     'CompositorWidgetChild.h',
     'CompositorWidgetParent.h',
     'InProcessWinCompositorWidget.h',
@@ -70,16 +71,17 @@ UNIFIED_SOURCES += [
     'ScreenHelperWin.cpp',
     'TaskbarPreview.cpp',
     'TaskbarPreviewButton.cpp',
     'TaskbarTabPreview.cpp',
     'TaskbarWindowPreview.cpp',
     'WidgetTraceEvent.cpp',
     'WinCompositorWindowThread.cpp',
     'WindowHook.cpp',
+    'WindowsConsole.cpp',
     'WinIMEHandler.cpp',
     'WinPointerEvents.cpp',
     'WinTaskbar.cpp',
     'WinTextEventDispatcherListener.cpp',
     'WinUtils.cpp',
 ]
 
 # The following files cannot be built in unified mode because of name clashes.