Bug 1576318 Part 4 - Add testing method to get the debugger requests and associated stacks for the current pause, r=loganfsmyth.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 30 Aug 2019 17:10:57 +0000
changeset 551412 aa75f0814cbe0364bfd545cea8be68e226cb09e0
parent 551411 607ed403709d8706e9328c438d16cb90add0ebd3
child 551413 ed6ce702ad2a72b94cf35e96d2567400cb31156a
push id11865
push userbtara@mozilla.com
push dateMon, 02 Sep 2019 08:54:37 +0000
treeherdermozilla-beta@37f59c4671b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersloganfsmyth
bugs1576318
milestone70.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 1576318 Part 4 - Add testing method to get the debugger requests and associated stacks for the current pause, r=loganfsmyth. Depends on D43320 Differential Revision: https://phabricator.services.mozilla.com/D43321
devtools/server/actors/replay/control.js
devtools/server/actors/replay/debugger.js
devtools/server/actors/thread.js
devtools/shared/specs/thread.js
--- a/devtools/server/actors/replay/control.js
+++ b/devtools/server/actors/replay/control.js
@@ -1028,16 +1028,23 @@ let gPauseMode = PauseModes.RUNNING;
 // In PAUSED or ARRIVING modes, the point we are paused at or sending the active
 // child to.
 let gPausePoint = null;
 
 // In PAUSED mode, any debugger requests that have been sent to the child.
 // In ARRIVING mode, the requests must be sent once the child arrives.
 const gDebuggerRequests = [];
 
+function addDebuggerRequest(request) {
+  gDebuggerRequests.push({
+    request,
+    stack: Error().stack,
+  });
+}
+
 function setPauseState(mode, point, child) {
   assert(mode);
   const idString = child ? ` #${child.id}` : "";
   dumpv(`SetPauseState ${mode} ${JSON.stringify(point)}${idString}`);
 
   gPauseMode = mode;
   gPausePoint = point;
   gActiveChild = child;
@@ -1072,17 +1079,17 @@ function sendActiveChildToPausePoint() {
       if (pointEquals(gActiveChild.pausePoint(), gPausePoint)) {
         setPauseState(PauseModes.PAUSED, gPausePoint, gActiveChild);
 
         // Send any debugger requests the child is considered to have received.
         if (gDebuggerRequests.length) {
           gActiveChild.sendManifest({
             contents: {
               kind: "batchDebuggerRequest",
-              requests: gDebuggerRequests,
+              requests: gDebuggerRequests.map(r => r.request),
             },
             onFinished(finishData) {
               assert(!finishData || !finishData.restoredCheckpoint);
             },
           });
         }
       } else {
         maybeReachPoint(gActiveChild, gPausePoint);
@@ -1818,17 +1825,17 @@ const gControl = {
       return { unhandledDivergence: true };
     }
 
     if (data.divergedFromRecording) {
       // Remember whether the child diverged from the recording.
       gActiveChild.divergedFromRecording = true;
     }
 
-    gDebuggerRequests.push(request);
+    addDebuggerRequest(request);
     return data.response;
   },
 
   // Synchronously send a debugger request to the main child, which will always
   // be at the end of the recording and can receive requests even when the
   // active child is not currently paused.
   sendRequestMainChild(request) {
     gMainChild.waitUntilPaused(true);
@@ -1855,25 +1862,29 @@ const gControl = {
       gLastFlushCheckpoint,
       checkpoint => findLogpointHits(checkpoint, logpoint)
     );
   },
 
   unscannedRegions,
   cachedPoints,
 
+  debuggerRequests() {
+    return gDebuggerRequests;
+  },
+
   getPauseData() {
     // If the child has not arrived at the pause point yet, see if there is
     // cached pause data for this point already which we can immediately return.
     if (gPauseMode == PauseModes.ARRIVING && !gDebuggerRequests.length) {
       const data = maybeGetPauseData(gPausePoint);
       if (data) {
         // After the child pauses, it will need to generate the pause data so
         // that any referenced objects will be instantiated.
-        gDebuggerRequests.push({ type: "pauseData" });
+        addDebuggerRequest({ type: "pauseData" });
         return data;
       }
     }
     gControl.maybeSwitchToReplayingChild();
     return gControl.sendRequest({ type: "pauseData" });
   },
 
   repaint() {
--- a/devtools/server/actors/replay/debugger.js
+++ b/devtools/server/actors/replay/debugger.js
@@ -115,16 +115,20 @@ ReplayDebugger.prototype = {
   replayUnscannedRegions() {
     return this._control.unscannedRegions();
   },
 
   replayCachedPoints() {
     return this._control.cachedPoints();
   },
 
+  replayDebuggerRequests() {
+    return this._control.debuggerRequests();
+  },
+
   addDebuggee() {},
   removeAllDebuggees() {},
 
   replayingContent(url) {
     return this._sendRequestMainChild({ type: "getContent", url });
   },
 
   _processResponse(request, response, divergeResponse) {
--- a/devtools/server/actors/thread.js
+++ b/devtools/server/actors/thread.js
@@ -2122,16 +2122,20 @@ const ThreadActor = ActorClassWithSpec(t
       breakpoints: this.breakpointActorMap.listKeys(),
     };
   },
 
   logLocation: function(prefix, frame) {
     const loc = this.sources.getFrameLocation(frame);
     dump(`${prefix} (${loc.line}, ${loc.column})\n`);
   },
+
+  debuggerRequests() {
+    return this.dbg.replayDebuggerRequests();
+  },
 });
 
 Object.assign(ThreadActor.prototype.requestTypes, {
   attach: ThreadActor.prototype.onAttach,
   detach: ThreadActor.prototype.onDetach,
   reconfigure: ThreadActor.prototype.onReconfigure,
   resume: ThreadActor.prototype.onResume,
   frames: ThreadActor.prototype.onFrames,
--- a/devtools/shared/specs/thread.js
+++ b/devtools/shared/specs/thread.js
@@ -149,12 +149,19 @@ const threadSpec = generateActorSpec({
       },
     },
     pauseOnExceptions: {
       request: {
         pauseOnExceptions: Arg(0, "string"),
         ignoreCaughtExceptions: Arg(1, "string"),
       },
     },
+
+    // For testing.
+    debuggerRequests: {
+      response: {
+        value: RetVal("array:json"),
+      },
+    },
   },
 });
 
 exports.threadSpec = threadSpec;