devtools: Fix available breakpoint positions with nested scripts (#38826)

in the [SpiderMonkey Debugger
API](https://firefox-source-docs.mozilla.org/js/Debugger/), there is a
separate
[Debugger.Script](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Script.html)
object for each function in a script, forming a tree of Script objects.
since we were only issuing
[getPossibleBreakpoints()](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Script.html#getpossiblebreakpoints-query)
queries to the [root Script
object](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.html#onnewscript-script-global)
for each script, we were failing to report locations inside functions as
available for setting breakpoints.

this patch fixes that by recursively issuing the
getPossibleBreakpoints() requests over the
[getChildScripts()](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.Script.html#getchildscripts)
tree.

Testing: this patch adds a new devtools test

Signed-off-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: atbrakhi <atbrakhi@igalia.com>
This commit is contained in:
shuppy 2025-08-21 19:00:32 +08:00 committed by GitHub
parent 7b4032e972
commit 4ba34b038c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 1 deletions

View file

@ -599,6 +599,22 @@ class DevtoolsTests(unittest.IsolatedAsyncioTestCase):
},
)
def test_source_breakable_lines_and_positions_with_functions(self):
self.start_web_server(test_dir=self.get_test_path("sources_breakable_lines_and_positions"))
self.run_servoshell(url=f"{self.base_urls[0]}/test_with_functions.html")
self.assert_source_breakable_lines_and_positions(
Source("inlineScript", f"{self.base_urls[0]}/test_with_functions.html"),
[5, 6, 7, 8, 9, 10],
{
"5": [8, 18],
"6": [12],
"7": [8],
"8": [4],
"9": [4],
"10": [0],
},
)
# Sets `base_url` and `web_server` and `web_server_thread`.
def start_web_server(self, *, test_dir=None, num_servers=2):
assert self.base_urls is None and self.web_servers is None and self.web_server_threads is None

View file

@ -0,0 +1,10 @@
<!doctype html>
<meta charset="utf-8">
<script>
function runContinuously() {
setTimeout(() => {
runContinuously();
}, 1000);
}
runContinuously();
</script>

View file

@ -38,5 +38,15 @@ addEventListener("addDebuggee", event => {
addEventListener("getPossibleBreakpoints", event => {
const {spidermonkeyId} = event;
getPossibleBreakpointsResult(event, sourceIdsToScripts.get(spidermonkeyId).getPossibleBreakpoints(/* TODO: `query` */));
const script = sourceIdsToScripts.get(spidermonkeyId);
function getPossibleBreakpointsRecursive(script) {
const result = script.getPossibleBreakpoints(/* TODO: `query` */);
for (const child of script.getChildScripts()) {
for (const location of getPossibleBreakpointsRecursive(child)) {
result.push(location);
}
}
return result;
}
getPossibleBreakpointsResult(event, getPossibleBreakpointsRecursive(script));
});