Closed Bug 1571791 Opened 6 years ago Closed 6 years ago

"Step in" across an await expression jumps to unexpected places

Categories

(DevTools :: Debugger, defect, P2)

defect

Tracking

(firefox70 fixed)

RESOLVED FIXED
Firefox 70
Tracking Status
firefox70 --- fixed

People

(Reporter: jimb, Assigned: jlast)

References

Details

(Whiteboard: [debugger-reserve])

Attachments

(1 file)

Load the following code into a page:

async function f() {
  let p = Promise.resolve(43);
  await p;
  console.log("after await");
}

function call_f() {
  Promise.resolve(42).then(forty_two => {
    console.log("interrupting microtask");
  });

  f().then(v => {
    console.log("promise of f's value resolved: " + v);
  });
}

Set a breakpoint to stop on the await p; statement, and then evaluate call_f() in the console. You should hit the breakpoint.

Then, press 'step into'. I would expect control to pause on the line following the await expression, but instead control pauses on the "interrupting microtask" line.

What's going on here is that, for the "step in" action, in addition to the onStep and onPop hook, the server also establishes an onEnterFrame hook to catch calls that occur during the step. Unfortunately, the await expression suspends the async call, and the next frame entry is in an entirely separate microtask, the callback for Promise.resolve(42) enqueued before we entered f at all. The onEnterFrame hook reports this extraneous frame entry, not realizing it's not a call instigated by the frame we started on.

One fix would be to clear the onEnterFrame hook when we get an onPop for a suspension, and then restore it when we resume execution in that frame, to make sure we do step into further calls in the right frame (consider the code f(await p): we do want to step into that call to f).

Another approach would be to filter onEnterFrame calls based on the parent frame - but since an unbounded amount of code could run during an await (imagine awaiting the result of an HTTP request, with the entire page remaining active while the async call is suspended), we'd be getting notifications of pretty much every function call that occurs anywhere during the suspension, only so that we can ignore them. This does not seem like a good idea.

Priority: -- → P2
Assignee: nobody → jlaster
Blocks: dbg-70
Status: NEW → ASSIGNED
Whiteboard: [debugger-reserve]

Note that we do not have to worry about the case where the debugger pauses at the await in f(await p): because await is not a valid breakpoint position.

Pushed by jlaster@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/9a55517ecc44 "Step in" across an await expression jumps to unexpected places. r=loganfsmyth
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 70
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: