Bug 1382968 - Only try to forward console messages from content processes to parent when browser console/toolbox are opened. r=jryans,tromey
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 01 Aug 2017 16:51:07 +0200
changeset 373712 5380b3782099
parent 373711 d0b89a730143
child 373713 ab16c50f1c29
push id32308
push userarchaeopteryx@coole-files.de
push dateThu, 10 Aug 2017 15:20:33 +0000
treeherdermozilla-central@5322c03f4c85 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans, tromey
bugs1382968
milestone57.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 1382968 - Only try to forward console messages from content processes to parent when browser console/toolbox are opened. r=jryans,tromey MozReview-Commit-ID: 8cFUbF4msHx
devtools/client/webconsole/webconsole-connection-proxy.js
devtools/server/actors/webconsole.js
devtools/server/actors/webconsole/content-process-forward.js
devtools/server/actors/webconsole/listeners.js
devtools/server/actors/webconsole/moz.build
toolkit/components/processsingleton/ContentProcessSingleton.js
toolkit/components/processsingleton/MainProcessSingleton.js
--- a/devtools/client/webconsole/webconsole-connection-proxy.js
+++ b/devtools/client/webconsole/webconsole-connection-proxy.js
@@ -173,16 +173,21 @@ WebConsoleConnectionProxy.prototype = {
 
   /**
    * Attach to the Web Console actor.
    * @private
    */
   _attachConsole: function () {
     let listeners = ["PageError", "ConsoleAPI", "NetworkActivity",
                      "FileActivity"];
+    // Enable the forwarding of console messages to the parent process
+    // when we open the Browser Console or Toolbox.
+    if (this.target.chrome && !this.target.isAddon) {
+      listeners.push("ContentProcessMessages");
+    }
     this.client.attachConsole(this._consoleActor, listeners,
                               this._onAttachConsole);
   },
 
   /**
    * The "attachConsole" response handler.
    *
    * @private
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -34,16 +34,17 @@ loader.lazyRequireGetter(this, "Environm
 // to load an unsupported module.
 if (isWorker) {
   loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/webconsole/worker-listeners", true);
   loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/worker-listeners", true);
 } else {
   loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/webconsole/listeners", true);
   loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/listeners", true);
   loader.lazyRequireGetter(this, "ConsoleReflowListener", "devtools/server/actors/webconsole/listeners", true);
+  loader.lazyRequireGetter(this, "ContentProcessListener", "devtools/server/actors/webconsole/listeners", true);
 }
 
 /**
  * The WebConsoleActor implements capabilities needed for the Web Console
  * feature.
  *
  * @constructor
  * @param object connection
@@ -363,16 +364,20 @@ WebConsoleActor.prototype =
     if (this.consoleReflowListener) {
       this.consoleReflowListener.destroy();
       this.consoleReflowListener = null;
     }
     if (this.serverLoggingListener) {
       this.serverLoggingListener.destroy();
       this.serverLoggingListener = null;
     }
+    if (this.contentProcessListener) {
+      this.contentProcessListener.destroy();
+      this.contentProcessListener = null;
+    }
 
     events.off(this.parentActor, "changed-toplevel-document",
                this._onChangedToplevelDocument);
 
     this.conn.removeActorPool(this._actorPool);
 
     if (this.parentActor.isRootActor) {
       Services.obs.removeObserver(this._onObserverNotification,
@@ -659,16 +664,26 @@ WebConsoleActor.prototype =
             break;
           }
           if (!this.serverLoggingListener) {
             this.serverLoggingListener =
               new ServerLoggingListener(this.window, this);
           }
           startedListeners.push(listener);
           break;
+        case "ContentProcessMessages":
+          // Workers don't support this message type
+          if (isWorker) {
+            break;
+          }
+          if (!this.contentProcessListener) {
+            this.contentProcessListener = new ContentProcessListener(this);
+          }
+          startedListeners.push(listener);
+          break;
       }
     }
 
     // Update the live list of running listeners
     startedListeners.forEach(this._listeners.add, this._listeners);
 
     return {
       startedListeners: startedListeners,
@@ -688,17 +703,17 @@ WebConsoleActor.prototype =
    */
   onStopListeners: function (request) {
     let stoppedListeners = [];
 
     // If no specific listeners are requested to be detached, we stop all
     // listeners.
     let toDetach = request.listeners ||
       ["PageError", "ConsoleAPI", "NetworkActivity",
-       "FileActivity", "ServerLogging"];
+       "FileActivity", "ServerLogging", "ContentProcessMessages"];
 
     while (toDetach.length > 0) {
       let listener = toDetach.shift();
       switch (listener) {
         case "PageError":
           if (this.consoleServiceListener) {
             this.consoleServiceListener.destroy();
             this.consoleServiceListener = null;
@@ -744,16 +759,23 @@ WebConsoleActor.prototype =
           break;
         case "ServerLogging":
           if (this.serverLoggingListener) {
             this.serverLoggingListener.destroy();
             this.serverLoggingListener = null;
           }
           stoppedListeners.push(listener);
           break;
+        case "ContentProcessMessages":
+          if (this.contentProcessListener) {
+            this.contentProcessListener.destroy();
+            this.contentProcessListener = null;
+          }
+          stoppedListeners.push(listener);
+          break;
       }
     }
 
     // Update the live list of running listeners
     stoppedListeners.forEach(this._listeners.delete, this._listeners);
 
     return { stoppedListeners: stoppedListeners };
   },
copy from toolkit/components/processsingleton/ContentProcessSingleton.js
copy to devtools/server/actors/webconsole/content-process-forward.js
--- a/toolkit/components/processsingleton/ContentProcessSingleton.js
+++ b/devtools/server/actors/webconsole/content-process-forward.js
@@ -2,25 +2,22 @@
  * 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/. */
 
 "use strict";
 
 const Cu = Components.utils;
 const Ci = Components.interfaces;
 
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIMessageSender");
-
-XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
-                                  "resource://gre/modules/TelemetryController.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
                                   "resource:///modules/E10SUtils.jsm");
 
 /*
  * The message manager has an upper limit on message sizes that it can
  * reliably forward to the parent so we limit the size of console log event
  * messages that we forward here. The web console is local and receives the
  * full console message, but addons subscribed to console event messages
@@ -35,92 +32,105 @@ XPCOMUtils.defineLazyModuleGetter(this, 
  * MSG_MGR_CONSOLE_INFO_MAX characters. We don't attempt to calculate
  * the exact amount of space the message manager implementation will require
  * for a given message so this is imperfect.
  */
 const MSG_MGR_CONSOLE_MAX_SIZE = 1024 * 1024; // 1MB
 const MSG_MGR_CONSOLE_VAR_SIZE = 8;
 const MSG_MGR_CONSOLE_INFO_MAX = 1024;
 
-function ContentProcessSingleton() {}
-ContentProcessSingleton.prototype = {
-  classID: Components.ID("{ca2a8470-45c7-11e4-916c-0800200c9a66}"),
+function ContentProcessForward() {
+  Services.obs.addObserver(this, "console-api-log-event");
+  Services.obs.addObserver(this, "xpcom-shutdown");
+  cpmm.addMessageListener("DevTools:StopForwardingContentProcessMessage", this);
+}
+ContentProcessForward.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
+  receiveMessage(message) {
+    if (message.name == "DevTools:StopForwardingContentProcessMessage") {
+      this.uninit();
+    }
+  },
+
   observe(subject, topic, data) {
     switch (topic) {
-    case "app-startup": {
-      Services.obs.addObserver(this, "console-api-log-event");
-      Services.obs.addObserver(this, "xpcom-shutdown");
-      TelemetryController.observe(null, topic, null);
-      break;
-    }
-    case "console-api-log-event": {
-      let consoleMsg = subject.wrappedJSObject;
+      case "console-api-log-event": {
+        let consoleMsg = subject.wrappedJSObject;
 
-      let msgData = {
-        level: consoleMsg.level,
-        filename: consoleMsg.filename.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
-        lineNumber: consoleMsg.lineNumber,
-        functionName: consoleMsg.functionName &&
-          consoleMsg.functionName.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
-        timeStamp: consoleMsg.timeStamp,
-        addonId: consoleMsg.addonId,
-        arguments: [],
-      };
+        let msgData = {
+          level: consoleMsg.level,
+          filename: consoleMsg.filename.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
+          lineNumber: consoleMsg.lineNumber,
+          functionName: consoleMsg.functionName &&
+            consoleMsg.functionName.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
+          timeStamp: consoleMsg.timeStamp,
+          addonId: consoleMsg.addonId,
+          arguments: [],
+        };
+
+        // We can't send objects over the message manager, so we sanitize
+        // them out, replacing those arguments with "<unavailable>".
+        let unavailString = "<unavailable>";
+        let unavailStringLength = unavailString.length * 2; // 2-bytes per char
 
-      // We can't send objects over the message manager, so we sanitize
-      // them out, replacing those arguments with "<unavailable>".
-      let unavailString = "<unavailable>";
-      let unavailStringLength = unavailString.length * 2; // 2-bytes per char
-
-      // When the sum of argument sizes reaches MSG_MGR_CONSOLE_MAX_SIZE,
-      // replace all arguments with "<truncated>".
-      let totalArgLength = 0;
+        // When the sum of argument sizes reaches MSG_MGR_CONSOLE_MAX_SIZE,
+        // replace all arguments with "<truncated>".
+        let totalArgLength = 0;
 
-      // Walk through the arguments, checking the type and size.
-      for (let arg of consoleMsg.arguments) {
-        if ((typeof arg == "object" || typeof arg == "function") &&
-            arg !== null) {
-          if (Services.appinfo.remoteType === E10SUtils.EXTENSION_REMOTE_TYPE) {
-            // For OOP extensions: we want the developer to be able to see the
-            // logs in the Browser Console. When the Addon Toolbox will be more
-            // prominent we can revisit.
-            try {
-              // If the argument is clonable, then send it as-is. If
-              // cloning fails, fall back to the unavailable string.
-              arg = Cu.cloneInto(arg, {});
-            } catch (e) {
+        // Walk through the arguments, checking the type and size.
+        for (let arg of consoleMsg.arguments) {
+          if ((typeof arg == "object" || typeof arg == "function") &&
+              arg !== null) {
+            if (Services.appinfo.remoteType === E10SUtils.EXTENSION_REMOTE_TYPE) {
+              // For OOP extensions: we want the developer to be able to see the
+              // logs in the Browser Console. When the Addon Toolbox will be more
+              // prominent we can revisit.
+              try {
+                // If the argument is clonable, then send it as-is. If
+                // cloning fails, fall back to the unavailable string.
+                arg = Cu.cloneInto(arg, {});
+              } catch (e) {
+                arg = unavailString;
+              }
+            } else {
               arg = unavailString;
             }
+            totalArgLength += unavailStringLength;
+          } else if (typeof arg == "string") {
+            totalArgLength += arg.length * 2; // 2-bytes per char
           } else {
-            arg = unavailString;
+            totalArgLength += MSG_MGR_CONSOLE_VAR_SIZE;
           }
-          totalArgLength += unavailStringLength;
-        } else if (typeof arg == "string") {
-          totalArgLength += arg.length * 2; // 2-bytes per char
-        } else {
-          totalArgLength += MSG_MGR_CONSOLE_VAR_SIZE;
+
+          if (totalArgLength <= MSG_MGR_CONSOLE_MAX_SIZE) {
+            msgData.arguments.push(arg);
+          } else {
+            // arguments take up too much space
+            msgData.arguments = ["<truncated>"];
+            break;
+          }
         }
 
-        if (totalArgLength <= MSG_MGR_CONSOLE_MAX_SIZE) {
-          msgData.arguments.push(arg);
-        } else {
-          // arguments take up too much space
-          msgData.arguments = ["<truncated>"];
-          break;
-        }
+        cpmm.sendAsyncMessage("Console:Log", msgData);
+        break;
       }
 
-      cpmm.sendAsyncMessage("Console:Log", msgData);
-      break;
-    }
-
-    case "xpcom-shutdown":
-      Services.obs.removeObserver(this, "console-api-log-event");
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-      break;
+      case "xpcom-shutdown":
+        this.uninit();
+        break;
     }
   },
+
+  uninit() {
+    Services.obs.removeObserver(this, "console-api-log-event");
+    Services.obs.removeObserver(this, "xpcom-shutdown");
+    cpmm.removeMessageListener("DevTools:StopForwardingContentProcessMessage", this);
+  }
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentProcessSingleton]);
+// loadProcessScript loads in all processes, including the parent,
+// in which we don't need any forwarding
+if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
+  new ContentProcessForward();
+}
+
--- a/devtools/server/actors/webconsole/listeners.js
+++ b/devtools/server/actors/webconsole/listeners.js
@@ -10,16 +10,19 @@ const Services = require("Services");
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 const {CONSOLE_WORKER_IDS, WebConsoleUtils} = require("devtools/server/actors/webconsole/utils");
 
 XPCOMUtils.defineLazyServiceGetter(this,
                                    "swm",
                                    "@mozilla.org/serviceworkers/manager;1",
                                    "nsIServiceWorkerManager");
 
+// Process script used to forward console calls from content processes to parent process
+const CONTENT_PROCESS_SCRIPT = "resource://devtools/server/actors/webconsole/content-process-forward.js";
+
 // The page errors listener
 
 /**
  * The nsIConsoleService listener. This is used to send all of the console
  * messages (JavaScript, CSS and more) to the remote Web Console instance.
  *
  * @constructor
  * @param nsIDOMWindow [window]
@@ -446,8 +449,44 @@ ConsoleReflowListener.prototype =
   /**
    * Unregister listener.
    */
   destroy: function () {
     this.docshell.removeWeakReflowObserver(this);
     this.listener = this.docshell = null;
   },
 };
+
+/**
+ * Forward console message calls from content processes to the parent process.
+ * Used by Browser console and toolbox to see messages from all processes.
+ *
+ * @constructor
+ * @param object owner
+ *        The listener owner which needs to implement:
+ *        - onConsoleAPICall(message)
+ */
+function ContentProcessListener(listener) {
+  this.listener = listener;
+
+  Services.ppmm.addMessageListener("Console:Log", this);
+  Services.ppmm.loadProcessScript(CONTENT_PROCESS_SCRIPT, true);
+}
+
+exports.ContentProcessListener = ContentProcessListener;
+
+ContentProcessListener.prototype = {
+  receiveMessage(message) {
+    let logMsg = message.data;
+    logMsg.wrappedJSObject = logMsg;
+    this.listener.onConsoleAPICall(logMsg);
+  },
+
+  destroy() {
+    // Tell the content processes to stop listening and forwarding messages
+    Services.ppmm.broadcastAsyncMessage("DevTools:StopForwardingContentProcessMessage");
+
+    Services.ppmm.removeMessageListener("Console:Log", this);
+    Services.ppmm.removeDelayedProcessScript(CONTENT_PROCESS_SCRIPT);
+
+    this.listener = null;
+  }
+};
--- a/devtools/server/actors/webconsole/moz.build
+++ b/devtools/server/actors/webconsole/moz.build
@@ -1,11 +1,12 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
+    'content-process-forward.js',
     'listeners.js',
     'utils.js',
     'worker-listeners.js',
 )
--- a/toolkit/components/processsingleton/ContentProcessSingleton.js
+++ b/toolkit/components/processsingleton/ContentProcessSingleton.js
@@ -5,122 +5,32 @@
 "use strict";
 
 const Cu = Components.utils;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
                                   "resource://gre/modules/TelemetryController.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
-                                  "resource:///modules/E10SUtils.jsm");
-
-/*
- * The message manager has an upper limit on message sizes that it can
- * reliably forward to the parent so we limit the size of console log event
- * messages that we forward here. The web console is local and receives the
- * full console message, but addons subscribed to console event messages
- * in the parent receive the truncated version. Due to fragmentation,
- * messages as small as 1MB have resulted in IPC allocation failures on
- * 32-bit platforms. To limit IPC allocation sizes, console.log messages
- * with arguments with total size > MSG_MGR_CONSOLE_MAX_SIZE (bytes) have
- * their arguments completely truncated. MSG_MGR_CONSOLE_VAR_SIZE is an
- * approximation of how much space (in bytes) a JS non-string variable will
- * require in the manager's implementation. For strings, we use 2 bytes per
- * char. The console message URI and function name are limited to
- * MSG_MGR_CONSOLE_INFO_MAX characters. We don't attempt to calculate
- * the exact amount of space the message manager implementation will require
- * for a given message so this is imperfect.
- */
-const MSG_MGR_CONSOLE_MAX_SIZE = 1024 * 1024; // 1MB
-const MSG_MGR_CONSOLE_VAR_SIZE = 8;
-const MSG_MGR_CONSOLE_INFO_MAX = 1024;
 
 function ContentProcessSingleton() {}
 ContentProcessSingleton.prototype = {
   classID: Components.ID("{ca2a8470-45c7-11e4-916c-0800200c9a66}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
   observe(subject, topic, data) {
     switch (topic) {
     case "app-startup": {
-      Services.obs.addObserver(this, "console-api-log-event");
       Services.obs.addObserver(this, "xpcom-shutdown");
       TelemetryController.observe(null, topic, null);
       break;
     }
-    case "console-api-log-event": {
-      let consoleMsg = subject.wrappedJSObject;
-
-      let msgData = {
-        level: consoleMsg.level,
-        filename: consoleMsg.filename.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
-        lineNumber: consoleMsg.lineNumber,
-        functionName: consoleMsg.functionName &&
-          consoleMsg.functionName.substring(0, MSG_MGR_CONSOLE_INFO_MAX),
-        timeStamp: consoleMsg.timeStamp,
-        addonId: consoleMsg.addonId,
-        arguments: [],
-      };
-
-      // We can't send objects over the message manager, so we sanitize
-      // them out, replacing those arguments with "<unavailable>".
-      let unavailString = "<unavailable>";
-      let unavailStringLength = unavailString.length * 2; // 2-bytes per char
-
-      // When the sum of argument sizes reaches MSG_MGR_CONSOLE_MAX_SIZE,
-      // replace all arguments with "<truncated>".
-      let totalArgLength = 0;
-
-      // Walk through the arguments, checking the type and size.
-      for (let arg of consoleMsg.arguments) {
-        if ((typeof arg == "object" || typeof arg == "function") &&
-            arg !== null) {
-          if (Services.appinfo.remoteType === E10SUtils.EXTENSION_REMOTE_TYPE) {
-            // For OOP extensions: we want the developer to be able to see the
-            // logs in the Browser Console. When the Addon Toolbox will be more
-            // prominent we can revisit.
-            try {
-              // If the argument is clonable, then send it as-is. If
-              // cloning fails, fall back to the unavailable string.
-              arg = Cu.cloneInto(arg, {});
-            } catch (e) {
-              arg = unavailString;
-            }
-          } else {
-            arg = unavailString;
-          }
-          totalArgLength += unavailStringLength;
-        } else if (typeof arg == "string") {
-          totalArgLength += arg.length * 2; // 2-bytes per char
-        } else {
-          totalArgLength += MSG_MGR_CONSOLE_VAR_SIZE;
-        }
-
-        if (totalArgLength <= MSG_MGR_CONSOLE_MAX_SIZE) {
-          msgData.arguments.push(arg);
-        } else {
-          // arguments take up too much space
-          msgData.arguments = ["<truncated>"];
-          break;
-        }
-      }
-
-      cpmm.sendAsyncMessage("Console:Log", msgData);
-      break;
-    }
-
     case "xpcom-shutdown":
-      Services.obs.removeObserver(this, "console-api-log-event");
       Services.obs.removeObserver(this, "xpcom-shutdown");
       break;
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentProcessSingleton]);
--- a/toolkit/components/processsingleton/MainProcessSingleton.js
+++ b/toolkit/components/processsingleton/MainProcessSingleton.js
@@ -13,22 +13,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/NetUtil.jsm");
 
 function MainProcessSingleton() {}
 MainProcessSingleton.prototype = {
   classID: Components.ID("{0636a680-45cb-11e4-916c-0800200c9a66}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
-  logConsoleMessage(message) {
-    let logMsg = message.data;
-    logMsg.wrappedJSObject = logMsg;
-    Services.obs.notifyObservers(logMsg, "console-api-log-event");
-  },
-
   // Called when a webpage calls window.external.AddSearchProvider
   addSearchEngine({ target: browser, data: { pageURL, engineURL } }) {
     pageURL = NetUtil.newURI(pageURL);
     engineURL = NetUtil.newURI(engineURL, null, pageURL);
 
     let iconURL;
     let tabbrowser = browser.getTabBrowser();
     if (browser.mIconURL && (!tabbrowser || tabbrowser.shouldLoadFavIcon(pageURL)))
@@ -68,23 +62,21 @@ MainProcessSingleton.prototype = {
     switch (topic) {
     case "app-startup": {
       Services.obs.addObserver(this, "xpcom-shutdown");
 
       // Load this script early so that console.* is initialized
       // before other frame scripts.
       Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true);
       Services.ppmm.loadProcessScript("chrome://global/content/process-content.js", true);
-      Services.ppmm.addMessageListener("Console:Log", this.logConsoleMessage);
       Services.mm.addMessageListener("Search:AddEngine", this.addSearchEngine);
       Services.ppmm.loadProcessScript("resource:///modules/ContentObservers.js", true);
       break;
     }
 
     case "xpcom-shutdown":
-      Services.ppmm.removeMessageListener("Console:Log", this.logConsoleMessage);
       Services.mm.removeMessageListener("Search:AddEngine", this.addSearchEngine);
       break;
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MainProcessSingleton]);