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

Commit 3114892

Browse files
Implement v8 Inspector Protocol (#329)
Debug agent now can choose to use either Inspector API (node >= 8) or v8 debug API.
1 parent 015f29c commit 3114892

16 files changed

+1725
-603
lines changed

package-lock.json

Lines changed: 39 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/agent/debugapi.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* Copyright 2017 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import * as semver from 'semver';
17+
18+
import * as apiTypes from '../types/api-types';
19+
import {Logger} from '../types/common-types';
20+
21+
import {DebugAgentConfig} from './config';
22+
import {ScanStats} from './scanner';
23+
import {SourceMapper} from './sourcemapper';
24+
25+
26+
export interface DebugApi {
27+
set: (breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void) => void;
28+
clear:
29+
(breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void) => void;
30+
wait:
31+
(breakpoint: apiTypes.Breakpoint,
32+
callback: (err?: Error) => void) => void;
33+
log:
34+
(breakpoint: apiTypes.Breakpoint,
35+
print: (format: string, exps: string[]) => void,
36+
shouldStop: () => boolean) => void;
37+
disconnect: () => void;
38+
numBreakpoints_: () => number;
39+
numListeners_: () => number;
40+
}
41+
42+
interface DebugApiConstructor {
43+
new(logger_: Logger, config_: DebugAgentConfig, jsFiles_: ScanStats,
44+
sourcemapper_: SourceMapper): DebugApi;
45+
}
46+
47+
class DummyDebugApi implements DebugApi {
48+
constructor(
49+
logger: Logger, _config: DebugAgentConfig, _jsFiles: ScanStats,
50+
_sourcemapper: SourceMapper) {
51+
logger.error(
52+
'Debug agent cannot get node version. Cloud debugger is disabled.');
53+
}
54+
set(_breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void): void {
55+
return setImmediate(() => {
56+
cb(new Error('no debugapi running.'));
57+
});
58+
}
59+
clear(_breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void): void {
60+
return setImmediate(() => {
61+
cb(new Error('no debugapi running.'));
62+
});
63+
}
64+
wait(_breakpoint: apiTypes.Breakpoint, cb: (err?: Error) => void): void {
65+
return setImmediate(() => {
66+
cb(new Error('no debugapi running.'));
67+
});
68+
}
69+
log:
70+
(breakpoint: apiTypes.Breakpoint,
71+
print: (format: string, exps: string[]) => void,
72+
shouldStop: () => boolean) => void;
73+
disconnect: () => void;
74+
numBreakpoints_: () => number;
75+
numListeners_: () => number;
76+
}
77+
78+
let debugApiConstructor: DebugApiConstructor;
79+
const nodeVersion = /v(\d+\.\d+\.\d+)/.exec(process.version);
80+
81+
if (!nodeVersion || nodeVersion.length < 2) {
82+
debugApiConstructor = DummyDebugApi;
83+
} else if (semver.satisfies(nodeVersion[1], '>=8')) {
84+
const inspectorapi = require('./inspectordebugapi');
85+
debugApiConstructor = inspectorapi.InspectorDebugApi;
86+
} else {
87+
const v8debugapi = require('./v8debugapi');
88+
debugApiConstructor = v8debugapi.V8DebugApi;
89+
}
90+
91+
export const MODULE_WRAP_PREFIX_LENGTH =
92+
require('module').wrap('☃').indexOf('☃');
93+
94+
let singleton: DebugApi;
95+
96+
export function create(
97+
logger: Logger, config: DebugAgentConfig, jsFiles: ScanStats,
98+
sourcemapper: SourceMapper): DebugApi {
99+
if (singleton && !config.forceNewAgent_) {
100+
return singleton;
101+
} else if (singleton) {
102+
singleton.disconnect();
103+
}
104+
105+
singleton = new debugApiConstructor(logger, config, jsFiles, sourcemapper);
106+
return singleton;
107+
}

src/agent/debuglet.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {StatusMessage} from '../status-message';
4040
import defaultConfig from './config';
4141
import * as scanner from './scanner';
4242
import * as SourceMapper from './sourcemapper';
43-
import * as v8debugapi from './v8debugapi';
43+
import * as debugapi from './debugapi';
4444

4545
const pjson = require('../../../package.json');
4646

@@ -50,7 +50,7 @@ import {Breakpoint} from '../types/api-types';
5050
import {DebugAgentConfig} from './config';
5151
import {Debug} from '../debug';
5252
import {Logger} from '../types/common-types';
53-
import {V8DebugApi} from './v8debugapi';
53+
import {DebugApi} from './debugapi';
5454

5555
const promisify = require('util.promisify');
5656

@@ -109,7 +109,7 @@ const formatBreakpoints = function(
109109

110110
export class Debuglet extends EventEmitter {
111111
private debug_: Debug;
112-
private v8debug_: V8DebugApi|null;
112+
private v8debug_: DebugApi|null;
113113
private running_: boolean;
114114
private project_: string|null;
115115
private debugletApi_: Controller;
@@ -249,7 +249,7 @@ export class Debuglet extends EventEmitter {
249249
const mapper = sourcemapper as SourceMapper.SourceMapper;
250250

251251
that.v8debug_ =
252-
v8debugapi.create(that.logger_, that.config_, jsStats, mapper);
252+
debugapi.create(that.logger_, that.config_, jsStats, mapper);
253253

254254
id = id || fileStats.hash;
255255

@@ -701,7 +701,7 @@ export class Debuglet extends EventEmitter {
701701
}
702702

703703
// TODO: Address the case when `that.v8debug_` is `null`.
704-
(that.v8debug_ as V8DebugApi).set(breakpoint, function(err1) {
704+
(that.v8debug_ as DebugApi).set(breakpoint, function(err1) {
705705
if (err1) {
706706
cb(err1);
707707
return;
@@ -713,7 +713,7 @@ export class Debuglet extends EventEmitter {
713713

714714
if (breakpoint.action === 'LOG') {
715715
// TODO: Address the case when `that.v8debug_` is `null`.
716-
(that.v8debug_ as V8DebugApi)
716+
(that.v8debug_ as DebugApi)
717717
.log(
718718
breakpoint,
719719
function(fmt: string, exprs: string[]) {
@@ -725,7 +725,7 @@ export class Debuglet extends EventEmitter {
725725
});
726726
} else {
727727
// TODO: Address the case when `that.v8debug_` is `null`.
728-
(that.v8debug_ as V8DebugApi).wait(breakpoint, function(err2) {
728+
(that.v8debug_ as DebugApi).wait(breakpoint, function(err2) {
729729
if (err2) {
730730
that.logger_.error(err2);
731731
cb(err2);

0 commit comments

Comments
 (0)