Skip to content
This repository was archived by the owner on Apr 3, 2024. It is now read-only.

Commit a26278e

Browse files
author
Matt Loring
committed
Prevent calls to deleted breakpoint listeners
1 parent 251e8aa commit a26278e

File tree

2 files changed

+44
-14
lines changed

2 files changed

+44
-14
lines changed

lib/v8debugapi.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ module.exports.create = function(logger_, config_, fileStats_) {
5959
var config = null;
6060
var fileStats = null;
6161
var breakpoints = {};
62+
// Entries map breakpoint id to { enabled: <bool>, listener: <function> }
6263
var listeners = {};
6364
var numBreakpoints = 0;
6465
// Before V8 4.5, having a debug listener active disables optimization. To
@@ -189,7 +190,7 @@ module.exports.create = function(logger_, config_, fileStats_) {
189190
var num = breakpoints[breakpoint.id].v8Breakpoint.number();
190191
var listener = onBreakpointHit.bind(
191192
null, breakpoint, function(err) {
192-
delete listeners[num];
193+
listeners[num].enabled = false;
193194
// This method is called from the debug event listener, which
194195
// swallows all exception. We defer the callback to make sure the
195196
// user errors aren't silenced.
@@ -198,7 +199,7 @@ module.exports.create = function(logger_, config_, fileStats_) {
198199
});
199200
});
200201

201-
listeners[num] = listener;
202+
listeners[num] = { enabled: true, listener: listener };
202203
},
203204

204205
/**
@@ -211,7 +212,7 @@ module.exports.create = function(logger_, config_, fileStats_) {
211212
null, breakpoint,
212213
createLogpointHandler(breakpoint, format, shouldStop, listener));
213214

214-
listeners[num] = listener;
215+
listeners[num] = { enabled: true, listener: listener };
215216
},
216217

217218
// The following are for testing:
@@ -341,12 +342,12 @@ module.exports.create = function(logger_, config_, fileStats_) {
341342
logsThisSecond++;
342343
console.log('LOGPOINT:', message);
343344
if (shouldStop()) {
344-
delete listeners[num];
345+
listeners[num].enabled = false;
345346
} else {
346347
if (logsThisSecond > config.log.maxLogsPerSecond) {
347-
delete listeners[num];
348+
listeners[num].enabled = false;
348349
setTimeout(function() {
349-
listeners[num] = listener;
350+
listeners[num].enabled = true;
350351
}, config.log.logDelaySeconds * 1000);
351352
}
352353
}
@@ -506,14 +507,20 @@ module.exports.create = function(logger_, config_, fileStats_) {
506507
* @param {Debug#BreakEvent} eventData
507508
*/
508509
function handleDebugEvents(evt, execState, eventData) {
509-
switch (evt) {
510-
case v8.DebugEvent.Break:
511-
eventData.breakPointsHit().forEach(function(hit) {
512-
var num = hit.script_break_point().number();
513-
logger.info('>>>V8 breakpoint hit<<< number: ' + num);
514-
listeners[num](execState, eventData);
515-
});
516-
break;
510+
try {
511+
switch (evt) {
512+
case v8.DebugEvent.Break:
513+
eventData.breakPointsHit().forEach(function(hit) {
514+
var num = hit.script_break_point().number();
515+
if (listeners[num].enabled) {
516+
logger.info('>>>V8 breakpoint hit<<< number: ' + num);
517+
listeners[num].listener(execState, eventData);
518+
}
519+
});
520+
break;
521+
}
522+
} catch (e) {
523+
logger.warn('Internal V8 error on breakpoint event: ' + e);
517524
}
518525
}
519526

test/test-v8debugapi.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,29 @@ describe('v8debugapi', function() {
403403

404404
});
405405

406+
it('should work with multiply hit breakpoints', function(done) {
407+
var oldWarn = logger.warn;
408+
var logCount = 0;
409+
// If an exception is thrown we will log
410+
logger.warn = function() { logCount++; };
411+
// clone a clean breakpointInFoo
412+
var bp = {id: breakpointInFoo.id, location: breakpointInFoo.location};
413+
api.set(bp, function(err) {
414+
assert.ifError(err);
415+
api.wait(bp, function(err) {
416+
assert.ifError(err);
417+
setTimeout(function() {
418+
logger.warn = oldWarn;
419+
assert.equal(logCount, 0);
420+
api.clear(bp);
421+
done();
422+
}, 100);
423+
});
424+
process.nextTick(function() {foo(1);});
425+
setTimeout(function() {foo(2);}, 50);
426+
});
427+
});
428+
406429
it('should be possible to wait on a logpoint without expressions',
407430
function(done) {
408431
var bp = {

0 commit comments

Comments
 (0)