Vm3 alpha debugger #295

Merged
rodrigorodriguez merged 29 commits from vm3-alpha-debugger into master 2022-11-29 22:05:10 +00:00
3 changed files with 43 additions and 40 deletions
Showing only changes of commit 9393081e58 - Show all commits

14
package-lock.json generated
View file

@ -43,7 +43,6 @@
"botframework-connector": "4.11.0",
"botlib": "1.10.9",
"c3-chart-maker": "^0.2.8",
"cd": "^0.3.3",
"chrome-remote-interface": "^0.31.3",
"cli-progress": "^3.11.2",
"cli-spinner": "0.2.10",
@ -8645,14 +8644,6 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"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": {
"version": "0.1.3",
"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",
"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": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",

View file

@ -32,21 +32,13 @@
'use strict';
import { GBError, GBLog, GBMinInstance } from 'botlib';
import { GBLog, GBMinInstance } from 'botlib';
import { GBServer } from '../../../src/app';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
import { GuaribasUser } from '../../security.gbapp/models';
import { DialogKeywords } from './DialogKeywords';
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
const Swagger = require('swagger-client');
const fs = require('fs');
import { CollectionUtil } from 'pragmatismo-io-framework';
import * as request from 'request-promise-native';
const urlJoin = require('url-join');
const Path = require('path');
const Fs = require('fs');
const url = require('url');
const { spawn } = require('child_process');
/**
* Web Automation services of conversation to be called by BASIC.
@ -83,6 +75,7 @@ export class DebuggerService {
debugWeb: boolean;
lastDebugWeb: Date;
/**
* 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].breaks = [];
GBServer.globals.debuggers[botId].stateInfo = "Stopped";
GBServer.globals.debuggers[botId].childProcess = null;
}
private client;
public async breakpoint({ botId, botApiKey, line }) {
public async breakpoint({ botId, line }) {
GBLog.info(`BASIC: Enabled breakpoint for ${botId} on ${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) {
const client = GBServer.globals.debuggers[botId].client;
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].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'};
}
public async step({ botId, botApiKey }) {
public async step({ botId }) {
if (GBServer.globals.debuggers[botId].state === 2) {
GBServer.globals.debuggers[botId].stateInfo = "Break";
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];
let messages = [];
if (this.client) {
@ -273,14 +272,24 @@ export class DebuggerService {
};
}
public async debug({ botId, botApiKey, scriptName }) {
public async getRunning({ botId, botApiKey, scriptName }) {
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) {
error = `Cannot DEBUG an already running process. ${botId}`;
return {error: error};
} else if (GBServer.globals.debuggers[botId].state === 2) {
GBLog.info(`BASIC: Releasing execution ${botId} in DEBUG mode.`);
await this.resume({ botId, botApiKey, force: false });
await this.resume({ botId});
return {status: 'OK'};
} else {
GBLog.info(`BASIC: Running ${botId} in DEBUG mode.`);

View file

@ -63,6 +63,7 @@ const createVm2Pool = ({ min, max, ...limits }) => {
{ cwd: limits.cwd, shell: false }
);
childProcess.stdout.on('data', data => {
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].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';
kill(process);
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;
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.
@ -124,7 +129,7 @@ const createVm2Pool = ({ min, max, ...limits }) => {
GBLog.info(`BASIC: Break at line ${frame.location.lineNumber + 1}`); // (zero-based)
GBServer.globals.debuggers[limits.botId].state = 2;
GBServer.globals.debuggers[limits.botId].stateInfo = "Break";
GBServer.globals.debuggers[limits.botId].stateInfo = 'Break';
} else {
GBLog.verbose(`BASIC: Configuring breakpoints if any for ${limits.botId}...`);
// Waits for debugger and setup breakpoints.
@ -149,19 +154,20 @@ const createVm2Pool = ({ min, max, ...limits }) => {
await client.Runtime.runIfWaitingForDebugger();
await client.Debugger.enable();
await client.Runtime.enable();
resolve(1);
} catch (err) {
GBLog.error(err);
kill(childProcess);
GBServer.globals.debuggers[limits.botId].state = 0;
GBServer.globals.debuggers[limits.botId].stateInfo = "Stopped";
GBServer.globals.debuggers[limits.botId].stateInfo = 'Stopped';
}
}).on('error', err => {
console.error(err);
kill(childProcess);
GBServer.globals.debuggers[limits.botId].state = 0;
GBServer.globals.debuggers[limits.botId].stateInfo = "Stopped";
GBServer.globals.debuggers[limits.botId].stateInfo = 'Stopped';
reject(err);
});
});
@ -169,6 +175,8 @@ const createVm2Pool = ({ min, max, ...limits }) => {
await debug();
}
socket = net.createConnection(childProcess.socket);
socket.write(JSON.stringify({ code, scope }) + '\n');
const timer = setTimeout(() => {
limitError = 'code execution took too long and was killed';