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

Commit

Permalink
Improve summarization of breakpoint capture
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Loring committed May 12, 2016
1 parent a67692d commit 5a39240
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 14 deletions.
4 changes: 2 additions & 2 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = {

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

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

// To limit the size of the buffer, we truncate long strings.
// A value of 0 disables truncation.
maxStringLength: 0
maxStringLength: 100
},

// These configuration options are for internal experimentation only.
Expand Down
24 changes: 20 additions & 4 deletions lib/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var BUFFER_FULL_MESSAGE_INDEX = 0;
var NATIVE_PROPERTY_MESSAGE_INDEX = 1;
var GETTER_MESSAGE_INDEX = 2;
var ARG_LOCAL_LIMIT_MESSAGE_INDEX = 3;
var OBJECT_LIMIT_MESSAGE_INDEX = 4;
var STRING_LIMIT_MESSAGE_INDEX = 5;

var MESSAGE_TABLE = [];
MESSAGE_TABLE[BUFFER_FULL_MESSAGE_INDEX] =
Expand All @@ -48,6 +50,16 @@ MESSAGE_TABLE[ARG_LOCAL_LIMIT_MESSAGE_INDEX] =
'Locals and arguments are only displayed for the ' +
'top `config.capture.maxExpandFrames` stack frames.',
true) };
MESSAGE_TABLE[OBJECT_LIMIT_MESSAGE_INDEX] =
{ status: new StatusMessage(StatusMessage.VARIABLE_VALUE,
'Only first `config.capture.maxProperties` elements' +
' were captured.',
false) };
MESSAGE_TABLE[STRING_LIMIT_MESSAGE_INDEX] =
{ status: new StatusMessage(StatusMessage.VARIABLE_VALUE,
'Only first `config.capture.maxStringLength` chars' +
' were captured.',
false) };

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

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

} else if (value.isObject()) {
data.varTableIndex = this.getVariableIndex_(value);
var maxProps = this.config_.capture.maxProperties;
if (maxProps && maxProps < Object.keys(value.value()).length) {
data.status = MESSAGE_TABLE[OBJECT_LIMIT_MESSAGE_INDEX];
}

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

StateResolver.prototype.getMirrorProperties_ = function(mirror) {
var numProperties = this.config_.capture.maxProperties;
var namedProperties = mirror.properties(1, numProperties);
var indexedProperties = mirror.properties(2, numProperties);
return namedProperties.concat(indexedProperties);
var properties = mirror.properties();
return numProperties ? properties.slice(0, numProperties) : properties;
};

StateResolver.prototype.resolveMirrorProperty_ = function(property) {
Expand Down
74 changes: 66 additions & 8 deletions test/test-v8debugapi.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */
/*2*/'use strict';
/*3*/function foo(n) {
/*4*/ var A = new Array(3); return n+42+A[0];
/*5*/}
/*6*/function getterObject() {
/*7*/ var hasGetter = { _a: 5, get a() { return this._a; }, b: 'hello world' };
/*8*/ return hasGetter.a;
/*9*/}
/*4*/ var A = [1, 2, 3]; var B = { a: 5, b: 6, c: 7 };
/*5*/ return n+42+A[0]+B.b;
/*6*/}
/*7*/function getterObject() {
/*8*/ var hasGetter = { _a: 5, get a() { return this._a; }, b: 'hello world' };
/*9*/ return hasGetter.a;
/*10*/}
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
Expand Down Expand Up @@ -449,6 +450,8 @@ describe('v8debugapi', function() {
location: breakpointInFoo.location,
expressions: ['process']
};
var oldMax = config.capture.maxProperties;
config.capture.maxProperties = 0;
api.set(bp, function(err) {
assert.ifError(err);
api.wait(bp, function(err) {
Expand Down Expand Up @@ -477,6 +480,7 @@ describe('v8debugapi', function() {
}));

api.clear(bp);
config.capture.maxProperties = oldMax;
done();
});
process.nextTick(function() {foo(3);});
Expand All @@ -486,7 +490,7 @@ describe('v8debugapi', function() {
it('should report error for native prop or getter', function(done) {
var bp = {
id: 'fake-id-124',
location: { path: 'test-v8debugapi.js', line: 8 },
location: { path: 'test-v8debugapi.js', line: 9 },
expressions: ['process.env', 'hasGetter']
};
api.set(bp, function(err) {
Expand Down Expand Up @@ -520,7 +524,7 @@ describe('v8debugapi', function() {
it('should limit string length', function(done) {
var bp = {
id: 'fake-id-124',
location: { path: 'test-v8debugapi.js', line: 8 },
location: { path: 'test-v8debugapi.js', line: 9 },
expressions: ['hasGetter']
};
var oldMax = config.capture.maxStringLength;
Expand All @@ -543,6 +547,60 @@ describe('v8debugapi', function() {
});
});

it('should limit array length', function(done) {
var bp = {
id: 'fake-id-124',
location: { path: 'test-v8debugapi.js', line: 5 },
expressions: ['A']
};
var oldMax = config.capture.maxProperties;
config.capture.maxProperties = 1;
api.set(bp, function(err) {
assert.ifError(err);
api.wait(bp, function(err) {
assert.ifError(err);
var foo = bp.evaluatedExpressions[0];
var fooVal = bp.variableTable[foo.varTableIndex];
assert.equal(fooVal.members.length, 1);
assert(foo.status.status.description.format.indexOf(
'Only first') !== -1);
assert(!foo.status.isError);

api.clear(bp);
config.capture.maxProperties = oldMax;
done();
});
process.nextTick(function() {foo(2);});
});
});

it('should limit object length', function(done) {
var bp = {
id: 'fake-id-124',
location: { path: 'test-v8debugapi.js', line: 5 },
expressions: ['B']
};
var oldMax = config.capture.maxProperties;
config.capture.maxProperties = 1;
api.set(bp, function(err) {
assert.ifError(err);
api.wait(bp, function(err) {
assert.ifError(err);
var foo = bp.evaluatedExpressions[0];
var fooVal = bp.variableTable[foo.varTableIndex];
assert.equal(fooVal.members.length, 1);
assert(foo.status.status.description.format.indexOf(
'Only first') !== -1);
assert(!foo.status.isError);

api.clear(bp);
config.capture.maxProperties = oldMax;
done();
});
process.nextTick(function() {foo(2);});
});
});

it('should capture without values for invalid watch expressions', function(done) {
// clone a clean breakpointInFoo
var bp = {
Expand Down

0 comments on commit 5a39240

Please sign in to comment.