Symptoms
This is related to the closed ticket #99, which describes the symptoms of this very problem.
You set a breakpoint, but the process isn't paused when that breakpoint is encountered and carries merrily on.
Environment
This is a remote debugging session between a Windows client (running Chrome devtools) and a remote Linux server (running node with --inspect=0.0.0.0).
What's wrong
By watching the websocket communication with Wireshark it is apparent that the Chrome Dev tools are using an incorrect filepath/URL when calling Debugger.setBreakpointByUrl.
What I am seeing
Request
{
"id": 17,
"method": "Debugger.setBreakpointByUrl",
"params": {
"lineNumber": 67,
"url": "EFS\\DEV-efsbastion\\username\\application\\projects\\service\\module\\index.js",
"columnNumber": 18,
"condition": ""
}
}Response
{
"id": 17,
"result": {
"breakpointId": "EFS\\DEV-efsbastion\\username\\application\\projects\\service\\module\\index.js:67:18",
"locations": []
}
}Note the empty locations array. I am no node debugger expert, but it feels like this locations array should be checked to ensure it is not empty after setting a new breakpoint marker before then showing the marker as active in the UI.
What I should be seeing
Request
{
"id": 17,
"method": "Debugger.setBreakpointByUrl",
"params": {
"lineNumber": 67,
"url": "/EFS/DEV-efsbastion/username/application/projects/service/module/index.js",
"columnNumber": 18,
"condition": ""
}
}Response
{
"id": 17,
"result": {
"breakpointId": "/EFS/DEV-efsbastion/username/application/projects/service/module/index.js:67:18",
"locations": [{
"scriptId":"104",
"lineNumber":67,
"columnNumber":18
}]
}
}Note the Linux path separators instead of Windows and the initial root slash on the path.
But isn't this a node bug?
No, it is not from what I can tell because of the following two discoveries.
PHPStorm
PHPStorm/WebStorm debugger continues to work just fine using it's URL regexes
Request
{
"id": 17,
"method": "Debugger.setBreakpointByUrl",
"params": {
"lineNumber": 67,
"urlRegex": "[/\\\\][iI][nN][dD][eE][xX]\\.[jJ][sS]([;?#!].*)?$"
}
}Response
{
"id": 17,
"result": {
"breakpointId": "/[/\\\\][iI][nN][dD][eE][xX]\\.[jJ][sS]([;?#!].*)?$/:67:18",
"locations": [{
"scriptId":"104",
"lineNumber":67,
"columnNumber":18
}]
}
}Manually recreating the request successfully
If I manually set the breakpoint myself I see a success response back over the websocket. For example consider the following code run from the Chrome console:
letid,key,socketid=1000key='<debugger-key-goes-here>'constconnect=userSuppliedKey=>{socket=newWebSocket(`ws://<ip-address-goes-here>:9229/${userSuppliedKey||key}`)socket.addEventListener('message',e=>{constd=JSON.parse(e.data)if(d){if(d.method==='Debugger.scriptParsed')returnconsole.log('scriptParsed',JSON.stringify({scriptId: d.params.scriptId,url: d.params.url}))if(d.method==='Debugger.breakpointResolved')returnconsole.log('breakpointResolved',JSON.stringify(Object.assign({breakpointId: d.params.breakpointId},d.params.location)))}console.info(`${e.data}`)})}constsend=(method,x)=>socket.send(JSON.stringify({id: ++id,method: `Debugger.${method}`,params: x}))const_getPossibleBps=(start,end)=>send('getPossibleBreakpoints',{ start, end })constgetPossibleBps=(scriptId,start,end)=>_getPossibleBps({ scriptId,lineNumber: start},{ scriptId,lineNumber: end})constsetBp=(lineNumber,url)=>send('setBreakpointByUrl',{ lineNumber, url,})constremoveBp=(lineNumber,url,columnNumber)=>send('removeBreakpoint',{breakpointId: `${url}:${lineNumber}:${columnNumber||0}`})constenable=()=>send('enable')Which gives us this when run in the Chrome console
connect('<debugger-key-goes-here>')// '<debugger-key-goes-here>'enable()// ...// scriptParsed {"scriptId":"104","url":"/EFS/DEV-efsbastion/username/application/projects/service/module/index.js"}// ...getPossibleBps('104',9,15)// {"id":1016,"result":{"locations":[{"scriptId":"104","lineNumber":9,"columnNumber":15},{"scriptId":"104","lineNumber":11,"columnNumber":15},{"scriptId":"104","lineNumber":12,"columnNumber":16},{"scriptId":"104","lineNumber":14,"columnNumber":4},{"scriptId":"104","lineNumber":15,"columnNumber":0},{"scriptId":"104","lineNumber":17,"columnNumber":4},{"scriptId":"104","lineNumber":18,"columnNumber":14}]}}setBp(11,'/EFS/DEV-efsbastion/username/application/projects/service/module/index.js')// {"id":1024,"result":{"breakpointId":"/EFS/DEV-efsbastion/username/application/projects/service/module/index.js:11:0","locations":[{"scriptId":"104","lineNumber":11,"columnNumber":15}]}}removeBp(11,'/EFS/DEV-efsbastion/username/application/projects/service/module/index.js')// {"id":1019,"result":{}}Possible introduction of the issue
https://chromium.googlesource.com/chromium/src/+/2140ffeadf3e081e2e0821fc8e1ee040373b205d%5E%21/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
in combination with https://chromium.googlesource.com/chromium/src/+blame/master/third_party/blink/renderer/devtools/front_end/common/ParsedURL.js#103
Symptoms
This is related to the closed ticket #99, which describes the symptoms of this very problem.
You set a breakpoint, but the process isn't paused when that breakpoint is encountered and carries merrily on.
Environment
This is a remote debugging session between a Windows client (running Chrome devtools) and a remote Linux server (running node with
--inspect=0.0.0.0).What's wrong
By watching the websocket communication with Wireshark it is apparent that the Chrome Dev tools are using an incorrect filepath/URL when calling
Debugger.setBreakpointByUrl.What I am seeing
Request
{ "id": 17, "method": "Debugger.setBreakpointByUrl", "params": { "lineNumber": 67, "url": "EFS\\DEV-efsbastion\\username\\application\\projects\\service\\module\\index.js", "columnNumber": 18, "condition": "" } }Response
{ "id": 17, "result": { "breakpointId": "EFS\\DEV-efsbastion\\username\\application\\projects\\service\\module\\index.js:67:18", "locations": [] } }Note the empty locations array. I am no node debugger expert, but it feels like this locations array should be checked to ensure it is not empty after setting a new breakpoint marker before then showing the marker as active in the UI.
What I should be seeing
Request
{ "id": 17, "method": "Debugger.setBreakpointByUrl", "params": { "lineNumber": 67, "url": "/EFS/DEV-efsbastion/username/application/projects/service/module/index.js", "columnNumber": 18, "condition": "" } }Response
{ "id": 17, "result": { "breakpointId": "/EFS/DEV-efsbastion/username/application/projects/service/module/index.js:67:18", "locations": [{ "scriptId":"104", "lineNumber":67, "columnNumber":18 }] } }Note the Linux path separators instead of Windows and the initial root slash on the path.
But isn't this a node bug?
No, it is not from what I can tell because of the following two discoveries.
PHPStorm
PHPStorm/WebStorm debugger continues to work just fine using it's URL regexes
Request
{ "id": 17, "method": "Debugger.setBreakpointByUrl", "params": { "lineNumber": 67, "urlRegex": "[/\\\\][iI][nN][dD][eE][xX]\\.[jJ][sS]([;?#!].*)?$" } }Response
{ "id": 17, "result": { "breakpointId": "/[/\\\\][iI][nN][dD][eE][xX]\\.[jJ][sS]([;?#!].*)?$/:67:18", "locations": [{ "scriptId":"104", "lineNumber":67, "columnNumber":18 }] } }Manually recreating the request successfully
If I manually set the breakpoint myself I see a success response back over the websocket. For example consider the following code run from the Chrome console:
Which gives us this when run in the Chrome console
Possible introduction of the issue
https://chromium.googlesource.com/chromium/src/+/2140ffeadf3e081e2e0821fc8e1ee040373b205d%5E%21/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
in combination with https://chromium.googlesource.com/chromium/src/+blame/master/third_party/blink/renderer/devtools/front_end/common/ParsedURL.js#103