Closed Bug 929116 Opened 11 years ago Closed 7 years ago

Setting breakpoints on eval scripts with a sourcemap

Categories

(DevTools :: Debugger, defect, P3)

defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: djvj, Unassigned)

References

(Blocks 1 open bug)

Details

Currently, if we |eval| a script with a //# sourceMappingURL=... annotation, then the foreign source file is added to the debugger.

However, breakpoints set on the foreign source file, in functions introduced by the eval-ed string, are not property set on the actual script.

Example:

test.coffee:
  window.fun = () -> {
    ...
  }

test.coffee is compiled to js, generating a source-map file "test.map", and the js-code evaled with:

eval(TEST_COFFEE_JS + "//# sourceMappingURL=test.map")

This causes test.coffee to show up as a file in the debugger, but breakpoints set within the coffeescript function aren't property set on the generated js code (and thus don't trigger when calling the eval-introduced function).
Component: Disability Access APIs → JavaScript Engine
Component: JavaScript Engine → Developer Tools: Debugger
Product: Core → Firefox
This is necessary for GWT debugging as well.
This is unrelated to the old, deprecated JSD API, so I'm updating the summary to avoid confusion.
Summary: JSD: Allow breakpoints to be set on eval-ed scripts with source maps. → Allow breakpoints to be set on eval-ed scripts with source maps.
Nick, I can help out with implementing this functionality.  Jim indicated that there were a number of steps required to fix this up (changing how the debugger associates filenames with scripts to use displayName as well as fileName, fixing line number info for eval scripts, etc.).

If you could describe those steps in more detail in the bug, and give me a heads up on where to get started, I can begin work on resolving them.
Flags: needinfo?(nfitzgerald)
The displayName is irrelevant here, that is for //# sourceURL directives.

Currently, all breakpoints are stored server side in the BreakpointStore[0]. The BreakpointStore saves the generated locations of breakpoints. One of the large (and false) assumptions we make in the debugger server is that sources are uniquely identifiable by URL. It was a compromise we had to make at the time. However, it is also what causes issues with eval'd scripts, since we don't end up storing them in the BreakpointStore because they don't have a URL.

I'm going to start cleaning up this mess and getting rid of that assumption sometime next quarter, but in the meantime we could make the assumption that D.Script#sourceMapURL can be a unique id for a source. Then, when we have an eval'd script with a source map, we can store the breakpoints in BreakpointStore by { sourceMapURL, line, column }. You'll also need to handle when we are adding new scripts (say because of a reload) and we are re-setting breakpoints[1] on those scripts.

As far as the line number offsets goes, I think that is just lineWhereTheEvalOccurs + lineInTheEvaledSource, Jim would know this stuff better than me. I think we would probably want to account for this in _setBreakpoint[2].


[0] http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/script.js#9

[1] http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/script.js#2206

[2] https://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/script.js#1358
Flags: needinfo?(nfitzgerald)
What do you mean by D.script? The unique ID has consequences for apps since we want to make sure breakpoints can be preserved across recompiles.

In GWT the URL containing the JavaScript that executes the eval() contains a sha1 hash based on the source code, so it's not stable across recompiles. The //#sourceURL should be stable. The //# sourceMappingUrl may or may not be stable, depending on whether it contains the hash.
(In reply to Brian Slesinsky from comment #5)
> What do you mean by D.script? The unique ID has consequences for apps since
> we want to make sure breakpoints can be preserved across recompiles.

D.Script is Debugger.Script, part of SpiderMonkey's debugger API: https://wiki.mozilla.org/Debugger

Agreed, we want to ensure that breakpoints can be preserved across recompiles.

> 
> In GWT the URL containing the JavaScript that executes the eval() contains a
> sha1 hash based on the source code, so it's not stable across recompiles.
> The //#sourceURL should be stable. The //# sourceMappingUrl may or may not
> be stable, depending on whether it contains the hash.

The idea I laid out above is for when we do not have //# sourceURL=... and only have a //# sourceMappingURL=..., if we had sourceURL, we could just use that in the BreakpointStore. We have a separate bug for supporting //# sourceURL=... directives: bug 833744.
Priority: -- → P3
This should be fixed automatically once bug 865313 lands, so what you proposed in comment 6 is a temporary workaround, correct?
Flags: needinfo?(nfitzgerald)
I believe so.
Flags: needinfo?(nfitzgerald)
Summary: Allow breakpoints to be set on eval-ed scripts with source maps. → Setting breakpoints on eval scripts with a sourcemap
I think this has been fixed for a while now, maybe even bug 865313 like Eddy said in comment #7.
I gave it a try locally using a source mapped eval and it seems to work fine.
Please reopen if I'm in error.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.