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

Commit

Permalink
Implement v8 Inspector Protocol (#329)
Browse files Browse the repository at this point in the history
Debug agent now can choose to use either Inspector API (node >= 8) or v8 debug API.
  • Loading branch information
gaofanmichael committed Sep 25, 2017
1 parent 015f29c commit 3114892
Show file tree
Hide file tree
Showing 16 changed files with 1,725 additions and 603 deletions.
70 changes: 39 additions & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 107 additions & 0 deletions src/agent/debugapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* Copyright 2017 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as semver from 'semver';

import * as apiTypes from '../types/api-types';
import {Logger} from '../types/common-types';

import {DebugAgentConfig} from './config';
import {ScanStats} from './scanner';
import {SourceMapper} from './sourcemapper';


export interface DebugApi {
set: (breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void) => void;
clear:
(breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void) => void;
wait:
(breakpoint: apiTypes.Breakpoint,
callback: (err?: Error) => void) => void;
log:
(breakpoint: apiTypes.Breakpoint,
print: (format: string, exps: string[]) => void,
shouldStop: () => boolean) => void;
disconnect: () => void;
numBreakpoints_: () => number;
numListeners_: () => number;
}

interface DebugApiConstructor {
new(logger_: Logger, config_: DebugAgentConfig, jsFiles_: ScanStats,
sourcemapper_: SourceMapper): DebugApi;
}

class DummyDebugApi implements DebugApi {
constructor(
logger: Logger, _config: DebugAgentConfig, _jsFiles: ScanStats,
_sourcemapper: SourceMapper) {
logger.error(
'Debug agent cannot get node version. Cloud debugger is disabled.');
}
set(_breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void): void {
return setImmediate(() => {
cb(new Error('no debugapi running.'));
});
}
clear(_breakpoint: apiTypes.Breakpoint, cb: (err: Error|null) => void): void {
return setImmediate(() => {
cb(new Error('no debugapi running.'));
});
}
wait(_breakpoint: apiTypes.Breakpoint, cb: (err?: Error) => void): void {
return setImmediate(() => {
cb(new Error('no debugapi running.'));
});
}
log:
(breakpoint: apiTypes.Breakpoint,
print: (format: string, exps: string[]) => void,
shouldStop: () => boolean) => void;
disconnect: () => void;
numBreakpoints_: () => number;
numListeners_: () => number;
}

let debugApiConstructor: DebugApiConstructor;
const nodeVersion = /v(\d+\.\d+\.\d+)/.exec(process.version);

if (!nodeVersion || nodeVersion.length < 2) {
debugApiConstructor = DummyDebugApi;
} else if (semver.satisfies(nodeVersion[1], '>=8')) {
const inspectorapi = require('./inspectordebugapi');
debugApiConstructor = inspectorapi.InspectorDebugApi;
} else {
const v8debugapi = require('./v8debugapi');
debugApiConstructor = v8debugapi.V8DebugApi;
}

export const MODULE_WRAP_PREFIX_LENGTH =
require('module').wrap('☃').indexOf('☃');

let singleton: DebugApi;

export function create(
logger: Logger, config: DebugAgentConfig, jsFiles: ScanStats,
sourcemapper: SourceMapper): DebugApi {
if (singleton && !config.forceNewAgent_) {
return singleton;
} else if (singleton) {
singleton.disconnect();
}

singleton = new debugApiConstructor(logger, config, jsFiles, sourcemapper);
return singleton;
}
14 changes: 7 additions & 7 deletions src/agent/debuglet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {StatusMessage} from '../status-message';
import defaultConfig from './config';
import * as scanner from './scanner';
import * as SourceMapper from './sourcemapper';
import * as v8debugapi from './v8debugapi';
import * as debugapi from './debugapi';

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

Expand All @@ -50,7 +50,7 @@ import {Breakpoint} from '../types/api-types';
import {DebugAgentConfig} from './config';
import {Debug} from '../debug';
import {Logger} from '../types/common-types';
import {V8DebugApi} from './v8debugapi';
import {DebugApi} from './debugapi';

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

Expand Down Expand Up @@ -109,7 +109,7 @@ const formatBreakpoints = function(

export class Debuglet extends EventEmitter {
private debug_: Debug;
private v8debug_: V8DebugApi|null;
private v8debug_: DebugApi|null;
private running_: boolean;
private project_: string|null;
private debugletApi_: Controller;
Expand Down Expand Up @@ -249,7 +249,7 @@ export class Debuglet extends EventEmitter {
const mapper = sourcemapper as SourceMapper.SourceMapper;

that.v8debug_ =
v8debugapi.create(that.logger_, that.config_, jsStats, mapper);
debugapi.create(that.logger_, that.config_, jsStats, mapper);

id = id || fileStats.hash;

Expand Down Expand Up @@ -701,7 +701,7 @@ export class Debuglet extends EventEmitter {
}

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

if (breakpoint.action === 'LOG') {
// TODO: Address the case when `that.v8debug_` is `null`.
(that.v8debug_ as V8DebugApi)
(that.v8debug_ as DebugApi)
.log(
breakpoint,
function(fmt: string, exprs: string[]) {
Expand All @@ -725,7 +725,7 @@ export class Debuglet extends EventEmitter {
});
} else {
// TODO: Address the case when `that.v8debug_` is `null`.
(that.v8debug_ as V8DebugApi).wait(breakpoint, function(err2) {
(that.v8debug_ as DebugApi).wait(breakpoint, function(err2) {
if (err2) {
that.logger_.error(err2);
cb(err2);
Expand Down

0 comments on commit 3114892

Please sign in to comment.