1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 const flags
= require("resource://devtools/shared/flags.js");
10 * A transport for the debugging protocol that uses nsIMessageManagers to
11 * exchange packets with servers running in child processes.
13 * In the parent process, |mm| should be the nsIMessageSender for the
14 * child process. In a child process, |mm| should be the child process
15 * message manager, which sends packets to the parent.
17 * |prefix| is a string included in the message names, to distinguish
18 * multiple servers running in the same child process.
20 * This transport exchanges messages named 'debug:<prefix>:packet', where
21 * <prefix> is |prefix|, whose data is the protocol packet.
23 function ChildDebuggerTransport(mm
, prefix
) {
25 this._messageName
= "debug:" + prefix
+ ":packet";
29 * To avoid confusion, we use 'message' to mean something that
30 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
33 ChildDebuggerTransport
.prototype = {
34 constructor: ChildDebuggerTransport
,
39 this._mm
.addMessageListener(this._messageName
, this);
44 this._mm
.removeMessageListener(this._messageName
, this);
46 if (e
.result
!= Cr
.NS_ERROR_NULL_POINTER
) {
49 // In some cases, especially when using messageManagers in non-e10s mode, we reach
50 // this point with a dead messageManager which only throws errors but does not
51 // seem to indicate in any other way that it is dead.
60 this._removeListener();
61 if (this.hooks
.onTransportClosed
) {
62 this.hooks
.onTransportClosed(null, options
);
66 receiveMessage({ data
}) {
67 this.hooks
.onPacket(data
);
71 * Helper method to ensure a given `object` can be sent across message manager
72 * without being serialized to JSON.
73 * See https://searchfox.org/mozilla-central/rev/6bfadf95b4a6aaa8bb3b2a166d6c3545983e179a/dom/base/nsFrameMessageManager.cpp#458-469
75 _canBeSerialized(object
) {
77 const holder
= new StructuredCloneHolder(
78 "ChildDebuggerTransport._canBeSerialized",
82 holder
.deserialize(this);
89 pathToUnserializable(object
) {
90 for (const key
in object
) {
91 const value
= object
[key
];
92 if (!this._canBeSerialized(value
)) {
93 if (typeof value
== "object") {
94 return [key
].concat(this.pathToUnserializable(value
));
103 if (flags
.testing
&& !this._canBeSerialized(packet
)) {
104 const attributes
= this.pathToUnserializable(packet
);
106 "Following packet can't be serialized: " + JSON
.stringify(packet
);
107 msg
+= "\nBecause of attributes: " + attributes
.join(", ") + "\n";
108 msg
+= "Did you pass a function or an XPCOM object in it?";
109 throw new Error(msg
);
112 this._mm
.sendAsyncMessage(this._messageName
, packet
);
114 if (e
.result
!= Cr
.NS_ERROR_NULL_POINTER
) {
117 // In some cases, especially when using messageManagers in non-e10s mode, we reach
118 // this point with a dead messageManager which only throws errors but does not
119 // seem to indicate in any other way that it is dead.
124 throw new Error("Can't send bulk data to child processes.");
128 exports
.ChildDebuggerTransport
= ChildDebuggerTransport
;