1
1
'use strict'
2
2
3
- const lock = require ( 'mutexify/promise' ) ( )
3
+ const mutex = require ( 'mutexify/promise' ) ( )
4
4
const { getGeneratedPosition } = require ( './source-maps' )
5
5
const session = require ( './session' )
6
6
const { compile : compileCondition , compileSegments, templateRequiresEvaluation } = require ( './condition' )
@@ -36,8 +36,9 @@ session.on('scriptLoadingStabilized', () => {
36
36
} )
37
37
38
38
module . exports = {
39
- addBreakpoint,
40
- removeBreakpoint
39
+ addBreakpoint : lock ( addBreakpoint ) ,
40
+ removeBreakpoint : lock ( removeBreakpoint ) ,
41
+ modifyBreakpoint : lock ( modifyBreakpoint )
41
42
}
42
43
43
44
async function addBreakpoint ( probe ) {
@@ -89,42 +90,36 @@ async function addBreakpoint (probe) {
89
90
throw new Error ( `Cannot compile expression: ${ probe . when . dsl } ` , { cause : err } )
90
91
}
91
92
92
- const release = await lock ( )
93
-
94
- try {
95
- const locationKey = generateLocationKey ( scriptId , lineNumber , columnNumber )
96
- const breakpoint = locationToBreakpoint . get ( locationKey )
97
-
98
- log . debug (
99
- '[debugger:devtools_client] %s breakpoint at %s:%d:%d (probe: %s, version: %d)' ,
100
- breakpoint ? 'Updating' : 'Adding' , url , lineNumber , columnNumber , probe . id , probe . version
101
- )
102
-
103
- if ( breakpoint ) {
104
- // A breakpoint already exists at this location, so we need to add the probe to the existing breakpoint
105
- await updateBreakpoint ( breakpoint , probe )
106
- } else {
107
- // No breakpoint exists at this location, so we need to create a new one
108
- const location = {
109
- scriptId,
110
- lineNumber : lineNumber - 1 , // Beware! lineNumber is zero-indexed
111
- columnNumber
112
- }
113
- let result
114
- try {
115
- result = await session . post ( 'Debugger.setBreakpoint' , {
116
- location,
117
- condition : probe . condition
118
- } )
119
- } catch ( err ) {
120
- throw new Error ( `Error setting breakpoint for probe ${ probe . id } ` , { cause : err } )
121
- }
122
- probeToLocation . set ( probe . id , locationKey )
123
- locationToBreakpoint . set ( locationKey , { id : result . breakpointId , location, locationKey } )
124
- breakpointToProbes . set ( result . breakpointId , new Map ( [ [ probe . id , probe ] ] ) )
93
+ const locationKey = generateLocationKey ( scriptId , lineNumber , columnNumber )
94
+ const breakpoint = locationToBreakpoint . get ( locationKey )
95
+
96
+ log . debug (
97
+ '[debugger:devtools_client] %s breakpoint at %s:%d:%d (probe: %s, version: %d)' ,
98
+ breakpoint ? 'Updating' : 'Adding' , url , lineNumber , columnNumber , probe . id , probe . version
99
+ )
100
+
101
+ if ( breakpoint ) {
102
+ // A breakpoint already exists at this location, so we need to add the probe to the existing breakpoint
103
+ await updateBreakpointInternal ( breakpoint , probe )
104
+ } else {
105
+ // No breakpoint exists at this location, so we need to create a new one
106
+ const location = {
107
+ scriptId,
108
+ lineNumber : lineNumber - 1 , // Beware! lineNumber is zero-indexed
109
+ columnNumber
110
+ }
111
+ let result
112
+ try {
113
+ result = await session . post ( 'Debugger.setBreakpoint' , {
114
+ location,
115
+ condition : probe . condition
116
+ } )
117
+ } catch ( err ) {
118
+ throw new Error ( `Error setting breakpoint for probe ${ probe . id } ` , { cause : err } )
125
119
}
126
- } finally {
127
- release ( )
120
+ probeToLocation . set ( probe . id , locationKey )
121
+ locationToBreakpoint . set ( locationKey , { id : result . breakpointId , location, locationKey } )
122
+ breakpointToProbes . set ( result . breakpointId , new Map ( [ [ probe . id , probe ] ] ) )
128
123
}
129
124
}
130
125
@@ -139,37 +134,37 @@ async function removeBreakpoint ({ id }) {
139
134
140
135
probes . delete ( id )
141
136
142
- const release = await lock ( )
137
+ const locationKey = probeToLocation . get ( id )
138
+ const breakpoint = locationToBreakpoint . get ( locationKey )
139
+ const probesAtLocation = breakpointToProbes . get ( breakpoint . id )
143
140
144
- try {
145
- const locationKey = probeToLocation . get ( id )
146
- const breakpoint = locationToBreakpoint . get ( locationKey )
147
- const probesAtLocation = breakpointToProbes . get ( breakpoint . id )
148
-
149
- probesAtLocation . delete ( id )
150
- probeToLocation . delete ( id )
151
-
152
- if ( probesAtLocation . size === 0 ) {
153
- locationToBreakpoint . delete ( locationKey )
154
- breakpointToProbes . delete ( breakpoint . id )
155
- if ( breakpointToProbes . size === 0 ) {
156
- await stop ( ) // TODO: Will this actually delete the breakpoint?
157
- } else {
158
- try {
159
- await session . post ( 'Debugger.removeBreakpoint' , { breakpointId : breakpoint . id } )
160
- } catch ( err ) {
161
- throw new Error ( `Error removing breakpoint for probe ${ id } ` , { cause : err } )
162
- }
163
- }
141
+ probesAtLocation . delete ( id )
142
+ probeToLocation . delete ( id )
143
+
144
+ if ( probesAtLocation . size === 0 ) {
145
+ locationToBreakpoint . delete ( locationKey )
146
+ breakpointToProbes . delete ( breakpoint . id )
147
+ if ( breakpointToProbes . size === 0 ) {
148
+ await stop ( ) // This will also remove the breakpoint
164
149
} else {
165
- await updateBreakpoint ( breakpoint )
150
+ try {
151
+ await session . post ( 'Debugger.removeBreakpoint' , { breakpointId : breakpoint . id } )
152
+ } catch ( err ) {
153
+ throw new Error ( `Error removing breakpoint for probe ${ id } ` , { cause : err } )
154
+ }
166
155
}
167
- } finally {
168
- release ( )
156
+ } else {
157
+ await updateBreakpointInternal ( breakpoint )
169
158
}
170
159
}
171
160
172
- async function updateBreakpoint ( breakpoint , probe ) {
161
+ // TODO: Modify existing probe instead of removing it (DEBUG-2817)
162
+ async function modifyBreakpoint ( probe ) {
163
+ await removeBreakpoint ( probe )
164
+ await addBreakpoint ( probe )
165
+ }
166
+
167
+ async function updateBreakpointInternal ( breakpoint , probe ) {
173
168
const probesAtLocation = breakpointToProbes . get ( breakpoint . id )
174
169
const conditionBeforeNewProbe = compileCompoundCondition ( Array . from ( probesAtLocation . values ( ) ) )
175
170
@@ -235,6 +230,17 @@ function stop () {
235
230
return session . post ( 'Debugger.disable' )
236
231
}
237
232
233
+ function lock ( fn ) {
234
+ return async function ( ...args ) {
235
+ const release = await mutex ( )
236
+ try {
237
+ return await fn ( ...args )
238
+ } finally {
239
+ release ( )
240
+ }
241
+ }
242
+ }
243
+
238
244
// Only if all probes have a condition can we use a compound condition.
239
245
// Otherwise, we need to evaluate each probe individually once the breakpoint is hit.
240
246
function compileCompoundCondition ( probes ) {
0 commit comments