Vm3 alpha debugger #295
3 changed files with 43 additions and 40 deletions
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -43,7 +43,6 @@
|
||||||
"botframework-connector": "4.11.0",
|
"botframework-connector": "4.11.0",
|
||||||
"botlib": "1.10.9",
|
"botlib": "1.10.9",
|
||||||
"c3-chart-maker": "^0.2.8",
|
"c3-chart-maker": "^0.2.8",
|
||||||
"cd": "^0.3.3",
|
|
||||||
"chrome-remote-interface": "^0.31.3",
|
"chrome-remote-interface": "^0.31.3",
|
||||||
"cli-progress": "^3.11.2",
|
"cli-progress": "^3.11.2",
|
||||||
"cli-spinner": "0.2.10",
|
"cli-spinner": "0.2.10",
|
||||||
|
@ -8645,14 +8644,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
||||||
},
|
},
|
||||||
"node_modules/cd": {
|
|
||||||
"version": "0.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/cd/-/cd-0.3.3.tgz",
|
|
||||||
"integrity": "sha512-X2y0Ssu48ucdkrNgCdg6k3EZWjWVy/dsEywUUTeZEIW31f3bQfq65Svm+TzU1Hz+qqhdmyCdjGhUvRsSKHl/mw==",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/center-align": {
|
"node_modules/center-align": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
||||||
|
@ -41049,11 +41040,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
||||||
},
|
},
|
||||||
"cd": {
|
|
||||||
"version": "0.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/cd/-/cd-0.3.3.tgz",
|
|
||||||
"integrity": "sha512-X2y0Ssu48ucdkrNgCdg6k3EZWjWVy/dsEywUUTeZEIW31f3bQfq65Svm+TzU1Hz+qqhdmyCdjGhUvRsSKHl/mw=="
|
|
||||||
},
|
|
||||||
"center-align": {
|
"center-align": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
||||||
|
|
|
@ -32,21 +32,13 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBError, GBLog, GBMinInstance } from 'botlib';
|
import { GBLog, GBMinInstance } from 'botlib';
|
||||||
import { GBServer } from '../../../src/app';
|
import { GBServer } from '../../../src/app';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
|
||||||
import { GuaribasUser } from '../../security.gbapp/models';
|
import { GuaribasUser } from '../../security.gbapp/models';
|
||||||
import { DialogKeywords } from './DialogKeywords';
|
import { DialogKeywords } from './DialogKeywords';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
|
||||||
const Swagger = require('swagger-client');
|
const Swagger = require('swagger-client');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
const { spawn } = require('child_process');
|
||||||
import * as request from 'request-promise-native';
|
|
||||||
|
|
||||||
const urlJoin = require('url-join');
|
|
||||||
const Path = require('path');
|
|
||||||
const Fs = require('fs');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web Automation services of conversation to be called by BASIC.
|
* Web Automation services of conversation to be called by BASIC.
|
||||||
|
@ -83,6 +75,7 @@ export class DebuggerService {
|
||||||
debugWeb: boolean;
|
debugWeb: boolean;
|
||||||
lastDebugWeb: Date;
|
lastDebugWeb: Date;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SYSTEM account maxLines,when used with impersonated contexts (eg. running in SET SCHEDULE).
|
* SYSTEM account maxLines,when used with impersonated contexts (eg. running in SET SCHEDULE).
|
||||||
*/
|
*/
|
||||||
|
@ -198,16 +191,17 @@ export class DebuggerService {
|
||||||
GBServer.globals.debuggers[botId].state = 0;
|
GBServer.globals.debuggers[botId].state = 0;
|
||||||
GBServer.globals.debuggers[botId].breaks = [];
|
GBServer.globals.debuggers[botId].breaks = [];
|
||||||
GBServer.globals.debuggers[botId].stateInfo = "Stopped";
|
GBServer.globals.debuggers[botId].stateInfo = "Stopped";
|
||||||
|
GBServer.globals.debuggers[botId].childProcess = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private client;
|
private client;
|
||||||
|
|
||||||
public async breakpoint({ botId, botApiKey, line }) {
|
public async breakpoint({ botId, line }) {
|
||||||
GBLog.info(`BASIC: Enabled breakpoint for ${botId} on ${line}.`);
|
GBLog.info(`BASIC: Enabled breakpoint for ${botId} on ${line}.`);
|
||||||
GBServer.globals.debuggers[botId].breaks.push(Number.parseInt(line));
|
GBServer.globals.debuggers[botId].breaks.push(Number.parseInt(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async resume({ botId, botApiKey, force }) {
|
public async resume({ botId }) {
|
||||||
if (GBServer.globals.debuggers[botId].state === 2) {
|
if (GBServer.globals.debuggers[botId].state === 2) {
|
||||||
const client = GBServer.globals.debuggers[botId].client;
|
const client = GBServer.globals.debuggers[botId].client;
|
||||||
await client.Debugger.resume();
|
await client.Debugger.resume();
|
||||||
|
@ -220,15 +214,20 @@ export class DebuggerService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async stop({ botId, botApiKey, force }) {
|
public async stop({ botId }) {
|
||||||
GBServer.globals.debuggers[botId].state = 0;
|
GBServer.globals.debuggers[botId].state = 0;
|
||||||
GBServer.globals.debuggers[botId].stateInfo = "Stopped";
|
GBServer.globals.debuggers[botId].stateInfo = "Stopped";
|
||||||
const client = GBServer.globals.debuggers[botId].client;
|
|
||||||
await client.Debugger.close();
|
const kill = ref => {
|
||||||
|
spawn('sh', ['-c', `pkill -9 -f ${ref}`]);
|
||||||
|
};
|
||||||
|
|
||||||
|
kill(GBServer.globals.debuggers[botId].childProcess);
|
||||||
|
|
||||||
return {status: 'OK'};
|
return {status: 'OK'};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async step({ botId, botApiKey }) {
|
public async step({ botId }) {
|
||||||
if (GBServer.globals.debuggers[botId].state === 2) {
|
if (GBServer.globals.debuggers[botId].state === 2) {
|
||||||
GBServer.globals.debuggers[botId].stateInfo = "Break";
|
GBServer.globals.debuggers[botId].stateInfo = "Break";
|
||||||
const client = GBServer.globals.debuggers[botId].client;
|
const client = GBServer.globals.debuggers[botId].client;
|
||||||
|
@ -240,7 +239,7 @@ export class DebuggerService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async context({ botId, botApiKey, force }) {
|
public async context({ botId }) {
|
||||||
const conversationId = this.conversationsMap[botId];
|
const conversationId = this.conversationsMap[botId];
|
||||||
let messages = [];
|
let messages = [];
|
||||||
if (this.client) {
|
if (this.client) {
|
||||||
|
@ -273,14 +272,24 @@ export class DebuggerService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async debug({ botId, botApiKey, scriptName }) {
|
public async getRunning({ botId, botApiKey, scriptName }) {
|
||||||
let error;
|
let error;
|
||||||
|
botId = botId[0]; // TODO: Handle call in POST.
|
||||||
|
if (!GBServer.globals.debuggers[botId])
|
||||||
|
{
|
||||||
|
GBServer.globals.debuggers[botId]= {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scriptName){
|
||||||
|
scriptName = 'start';
|
||||||
|
}
|
||||||
|
|
||||||
if (GBServer.globals.debuggers[botId].state === 1) {
|
if (GBServer.globals.debuggers[botId].state === 1) {
|
||||||
error = `Cannot DEBUG an already running process. ${botId}`;
|
error = `Cannot DEBUG an already running process. ${botId}`;
|
||||||
return {error: error};
|
return {error: error};
|
||||||
} else if (GBServer.globals.debuggers[botId].state === 2) {
|
} else if (GBServer.globals.debuggers[botId].state === 2) {
|
||||||
GBLog.info(`BASIC: Releasing execution ${botId} in DEBUG mode.`);
|
GBLog.info(`BASIC: Releasing execution ${botId} in DEBUG mode.`);
|
||||||
await this.resume({ botId, botApiKey, force: false });
|
await this.resume({ botId});
|
||||||
return {status: 'OK'};
|
return {status: 'OK'};
|
||||||
} else {
|
} else {
|
||||||
GBLog.info(`BASIC: Running ${botId} in DEBUG mode.`);
|
GBLog.info(`BASIC: Running ${botId} in DEBUG mode.`);
|
||||||
|
|
|
@ -63,6 +63,7 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
{ cwd: limits.cwd, shell: false }
|
{ cwd: limits.cwd, shell: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
childProcess.stdout.on('data', data => {
|
childProcess.stdout.on('data', data => {
|
||||||
childProcess.socket = childProcess.socket || data.toString().trim();
|
childProcess.socket = childProcess.socket || data.toString().trim();
|
||||||
});
|
});
|
||||||
|
@ -75,18 +76,22 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
GBServer.globals.debuggers[limits.botId].state = 0;
|
GBServer.globals.debuggers[limits.botId].state = 0;
|
||||||
GBServer.globals.debuggers[limits.botId].stateInfo = stderrCache;
|
GBServer.globals.debuggers[limits.botId].stateInfo = stderrCache;
|
||||||
}
|
}
|
||||||
if (stderrCache.includes('FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory')) {
|
else if (stderrCache.includes('FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory')) {
|
||||||
limitError = 'code execution exceeed allowed memory';
|
limitError = 'code execution exceeed allowed memory';
|
||||||
kill(process);
|
kill(process);
|
||||||
GBServer.globals.debuggers[limits.botId].state = 0;
|
GBServer.globals.debuggers[limits.botId].state = 0;
|
||||||
GBServer.globals.debuggers[limits.botId].stateInfo = "Fail";
|
GBServer.globals.debuggers[limits.botId].stateInfo = 'Fail';
|
||||||
|
}
|
||||||
|
else if (stderrCache.includes('Debugger attached.')) {
|
||||||
|
GBLog.info(`BASIC: General Bots Debugger attached to Node .gbdialog process for ${limits.botId}.`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let socket = null;
|
let socket = null;
|
||||||
await waitUntil(() => childProcess.socket);
|
await waitUntil(() => childProcess.socket);
|
||||||
socket = net.createConnection(childProcess.socket);
|
|
||||||
socket.write(JSON.stringify({ code, scope }) + '\n');
|
GBServer.globals.debuggers[limits.botId].childProcess = ref;
|
||||||
|
|
||||||
|
|
||||||
// Only attach if called by debugger/run.
|
// Only attach if called by debugger/run.
|
||||||
|
|
||||||
|
@ -124,7 +129,7 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
GBLog.info(`BASIC: Break at line ${frame.location.lineNumber + 1}`); // (zero-based)
|
GBLog.info(`BASIC: Break at line ${frame.location.lineNumber + 1}`); // (zero-based)
|
||||||
|
|
||||||
GBServer.globals.debuggers[limits.botId].state = 2;
|
GBServer.globals.debuggers[limits.botId].state = 2;
|
||||||
GBServer.globals.debuggers[limits.botId].stateInfo = "Break";
|
GBServer.globals.debuggers[limits.botId].stateInfo = 'Break';
|
||||||
} else {
|
} else {
|
||||||
GBLog.verbose(`BASIC: Configuring breakpoints if any for ${limits.botId}...`);
|
GBLog.verbose(`BASIC: Configuring breakpoints if any for ${limits.botId}...`);
|
||||||
// Waits for debugger and setup breakpoints.
|
// Waits for debugger and setup breakpoints.
|
||||||
|
@ -150,18 +155,19 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
await client.Debugger.enable();
|
await client.Debugger.enable();
|
||||||
await client.Runtime.enable();
|
await client.Runtime.enable();
|
||||||
|
|
||||||
|
|
||||||
resolve(1);
|
resolve(1);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
GBLog.error(err);
|
GBLog.error(err);
|
||||||
kill(childProcess);
|
kill(childProcess);
|
||||||
GBServer.globals.debuggers[limits.botId].state = 0;
|
GBServer.globals.debuggers[limits.botId].state = 0;
|
||||||
GBServer.globals.debuggers[limits.botId].stateInfo = "Stopped";
|
GBServer.globals.debuggers[limits.botId].stateInfo = 'Stopped';
|
||||||
}
|
}
|
||||||
}).on('error', err => {
|
}).on('error', err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
kill(childProcess);
|
kill(childProcess);
|
||||||
GBServer.globals.debuggers[limits.botId].state = 0;
|
GBServer.globals.debuggers[limits.botId].state = 0;
|
||||||
GBServer.globals.debuggers[limits.botId].stateInfo = "Stopped";
|
GBServer.globals.debuggers[limits.botId].stateInfo = 'Stopped';
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -169,6 +175,8 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
|
|
||||||
await debug();
|
await debug();
|
||||||
}
|
}
|
||||||
|
socket = net.createConnection(childProcess.socket);
|
||||||
|
socket.write(JSON.stringify({ code, scope }) + '\n');
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
limitError = 'code execution took too long and was killed';
|
limitError = 'code execution took too long and was killed';
|
||||||
|
|
Loading…
Add table
Reference in a new issue