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

Commit 5a39240

Browse files
author
Matt Loring
committed
Improve summarization of breakpoint capture
1 parent a67692d commit 5a39240

File tree

3 files changed

+88
-14
lines changed

3 files changed

+88
-14
lines changed

config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ module.exports = {
5353

5454
// To reduce the overall capture time, limit the number of properties
5555
// gathered on large object. A value of 0 disables the limit.
56-
maxProperties: 0,
56+
maxProperties: 10,
5757

5858
// Total 'size' of data to gather. This is NOT the number of bytes of data
5959
// that are sent over the wire, but instead a very very coarse approximation
@@ -65,7 +65,7 @@ module.exports = {
6565

6666
// To limit the size of the buffer, we truncate long strings.
6767
// A value of 0 disables truncation.
68-
maxStringLength: 0
68+
maxStringLength: 100
6969
},
7070

7171
// These configuration options are for internal experimentation only.

lib/state.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ var BUFFER_FULL_MESSAGE_INDEX = 0;
3232
var NATIVE_PROPERTY_MESSAGE_INDEX = 1;
3333
var GETTER_MESSAGE_INDEX = 2;
3434
var ARG_LOCAL_LIMIT_MESSAGE_INDEX = 3;
35+
var OBJECT_LIMIT_MESSAGE_INDEX = 4;
36+
var STRING_LIMIT_MESSAGE_INDEX = 5;
3537

3638
var MESSAGE_TABLE = [];
3739
MESSAGE_TABLE[BUFFER_FULL_MESSAGE_INDEX] =
@@ -48,6 +50,16 @@ MESSAGE_TABLE[ARG_LOCAL_LIMIT_MESSAGE_INDEX] =
4850
'Locals and arguments are only displayed for the ' +
4951
'top `config.capture.maxExpandFrames` stack frames.',
5052
true) };
53+
MESSAGE_TABLE[OBJECT_LIMIT_MESSAGE_INDEX] =
54+
{ status: new StatusMessage(StatusMessage.VARIABLE_VALUE,
55+
'Only first `config.capture.maxProperties` elements' +
56+
' were captured.',
57+
false) };
58+
MESSAGE_TABLE[STRING_LIMIT_MESSAGE_INDEX] =
59+
{ status: new StatusMessage(StatusMessage.VARIABLE_VALUE,
60+
'Only first `config.capture.maxStringLength` chars' +
61+
' were captured.',
62+
false) };
5163

5264
/**
5365
* Captures the stack and current execution state.
@@ -347,15 +359,20 @@ StateResolver.prototype.resolveVariable_ = function(name, value) {
347359
// primitives: undefined, null, boolean, number, string, symbol
348360
data.value = value.toText();
349361
var maxLength = this.config_.capture.maxStringLength;
350-
if (maxLength) {
362+
if (maxLength && maxLength < data.value.length) {
351363
data.value = data.value.substring(0, maxLength) + '...';
364+
data.status = MESSAGE_TABLE[STRING_LIMIT_MESSAGE_INDEX];
352365
}
353366

354367
} else if (value.isFunction()) {
355368
data.value = 'function ' + this.resolveFunctionName_(value) + '()';
356369

357370
} else if (value.isObject()) {
358371
data.varTableIndex = this.getVariableIndex_(value);
372+
var maxProps = this.config_.capture.maxProperties;
373+
if (maxProps && maxProps < Object.keys(value.value()).length) {
374+
data.status = MESSAGE_TABLE[OBJECT_LIMIT_MESSAGE_INDEX];
375+
}
359376

360377
} else {
361378
// PropertyMirror, InternalPropertyMirror, FrameMirror, ScriptMirror
@@ -437,9 +454,8 @@ StateResolver.prototype.resolveMirrorFast_ = function(mirror) {
437454

438455
StateResolver.prototype.getMirrorProperties_ = function(mirror) {
439456
var numProperties = this.config_.capture.maxProperties;
440-
var namedProperties = mirror.properties(1, numProperties);
441-
var indexedProperties = mirror.properties(2, numProperties);
442-
return namedProperties.concat(indexedProperties);
457+
var properties = mirror.properties();
458+
return numProperties ? properties.slice(0, numProperties) : properties;
443459
};
444460

445461
StateResolver.prototype.resolveMirrorProperty_ = function(property) {

test/test-v8debugapi.js

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */
22
/*2*/'use strict';
33
/*3*/function foo(n) {
4-
/*4*/ var A = new Array(3); return n+42+A[0];
5-
/*5*/}
6-
/*6*/function getterObject() {
7-
/*7*/ var hasGetter = { _a: 5, get a() { return this._a; }, b: 'hello world' };
8-
/*8*/ return hasGetter.a;
9-
/*9*/}
4+
/*4*/ var A = [1, 2, 3]; var B = { a: 5, b: 6, c: 7 };
5+
/*5*/ return n+42+A[0]+B.b;
6+
/*6*/}
7+
/*7*/function getterObject() {
8+
/*8*/ var hasGetter = { _a: 5, get a() { return this._a; }, b: 'hello world' };
9+
/*9*/ return hasGetter.a;
10+
/*10*/}
1011
/**
1112
* Copyright 2015 Google Inc. All Rights Reserved.
1213
*
@@ -449,6 +450,8 @@ describe('v8debugapi', function() {
449450
location: breakpointInFoo.location,
450451
expressions: ['process']
451452
};
453+
var oldMax = config.capture.maxProperties;
454+
config.capture.maxProperties = 0;
452455
api.set(bp, function(err) {
453456
assert.ifError(err);
454457
api.wait(bp, function(err) {
@@ -477,6 +480,7 @@ describe('v8debugapi', function() {
477480
}));
478481

479482
api.clear(bp);
483+
config.capture.maxProperties = oldMax;
480484
done();
481485
});
482486
process.nextTick(function() {foo(3);});
@@ -486,7 +490,7 @@ describe('v8debugapi', function() {
486490
it('should report error for native prop or getter', function(done) {
487491
var bp = {
488492
id: 'fake-id-124',
489-
location: { path: 'test-v8debugapi.js', line: 8 },
493+
location: { path: 'test-v8debugapi.js', line: 9 },
490494
expressions: ['process.env', 'hasGetter']
491495
};
492496
api.set(bp, function(err) {
@@ -520,7 +524,7 @@ describe('v8debugapi', function() {
520524
it('should limit string length', function(done) {
521525
var bp = {
522526
id: 'fake-id-124',
523-
location: { path: 'test-v8debugapi.js', line: 8 },
527+
location: { path: 'test-v8debugapi.js', line: 9 },
524528
expressions: ['hasGetter']
525529
};
526530
var oldMax = config.capture.maxStringLength;
@@ -543,6 +547,60 @@ describe('v8debugapi', function() {
543547
});
544548
});
545549

550+
it('should limit array length', function(done) {
551+
var bp = {
552+
id: 'fake-id-124',
553+
location: { path: 'test-v8debugapi.js', line: 5 },
554+
expressions: ['A']
555+
};
556+
var oldMax = config.capture.maxProperties;
557+
config.capture.maxProperties = 1;
558+
api.set(bp, function(err) {
559+
assert.ifError(err);
560+
api.wait(bp, function(err) {
561+
assert.ifError(err);
562+
var foo = bp.evaluatedExpressions[0];
563+
var fooVal = bp.variableTable[foo.varTableIndex];
564+
assert.equal(fooVal.members.length, 1);
565+
assert(foo.status.status.description.format.indexOf(
566+
'Only first') !== -1);
567+
assert(!foo.status.isError);
568+
569+
api.clear(bp);
570+
config.capture.maxProperties = oldMax;
571+
done();
572+
});
573+
process.nextTick(function() {foo(2);});
574+
});
575+
});
576+
577+
it('should limit object length', function(done) {
578+
var bp = {
579+
id: 'fake-id-124',
580+
location: { path: 'test-v8debugapi.js', line: 5 },
581+
expressions: ['B']
582+
};
583+
var oldMax = config.capture.maxProperties;
584+
config.capture.maxProperties = 1;
585+
api.set(bp, function(err) {
586+
assert.ifError(err);
587+
api.wait(bp, function(err) {
588+
assert.ifError(err);
589+
var foo = bp.evaluatedExpressions[0];
590+
var fooVal = bp.variableTable[foo.varTableIndex];
591+
assert.equal(fooVal.members.length, 1);
592+
assert(foo.status.status.description.format.indexOf(
593+
'Only first') !== -1);
594+
assert(!foo.status.isError);
595+
596+
api.clear(bp);
597+
config.capture.maxProperties = oldMax;
598+
done();
599+
});
600+
process.nextTick(function() {foo(2);});
601+
});
602+
});
603+
546604
it('should capture without values for invalid watch expressions', function(done) {
547605
// clone a clean breakpointInFoo
548606
var bp = {

0 commit comments

Comments
 (0)