From 3111c46e92cdcf8256d9b59cb2a66ee3a9e82698 Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 3 Jul 2015 03:09:42 +0400 Subject: [PATCH 1/9] add breakpoint path remapping to allow debugging meteor apps --- package.json | 4 ++-- plugins/c9.ide.terminal/link_handler.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index dbdd3b95..453716db 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#2bc3f31089", + "c9.ide.run.debug": "#5edf7086bc", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", @@ -102,7 +102,7 @@ "c9.ide.recentfiles": "#7c099abf40", "c9.ide.remote": "#301d2ab519", "c9.ide.processlist": "#bc11818bb5", - "c9.ide.run": "#c53178c339", + "c9.ide.run": "#fd32560361", "c9.ide.run.build": "#0598fff697", "c9.ide.run.debug.xdebug": "#61dcbd0180", "c9.ide.save": "#e00549cb0f", diff --git a/plugins/c9.ide.terminal/link_handler.js b/plugins/c9.ide.terminal/link_handler.js index bce11fb9..fb744d5c 100644 --- a/plugins/c9.ide.terminal/link_handler.js +++ b/plugins/c9.ide.terminal/link_handler.js @@ -184,6 +184,7 @@ define(function(require, exports, module) { // Make sure home dir is marked correctly path = path.replace(reHome, "~"); + if (path[0] != "/") path = "/" + path; fs.stat(path, function(err, stat) { if (err) { From 6a6fdd694041be60e7aeb1e736855bb07308d17d Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 6 Sep 2015 19:08:38 +0400 Subject: [PATCH 2/9] fix broken bashspawn on windows --- node_modules/vfs-local/localfs.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/node_modules/vfs-local/localfs.js b/node_modules/vfs-local/localfs.js index d834f4ea..12fac9dd 100644 --- a/node_modules/vfs-local/localfs.js +++ b/node_modules/vfs-local/localfs.js @@ -1955,7 +1955,10 @@ module.exports = function setup(fsOptions) { } } - function PtyStream(pty, isOutput){ + function PtyStream(pty, isOutput, old){ + if (old) { + return old.attachTo(pty, isOutput); + } var exited = false; var killed = false; @@ -1975,6 +1978,18 @@ module.exports = function setup(fsOptions) { pty.kill = function() {}; } + this.attachTo = function(newPty) { + pty = newPty; + exited = false; + killed = false; + + this.readable = true; + this.writable = true; + + Object.keys(events).forEach(forwardEvent); + return this; + } + this.killtree = this.kill = isOutput ? function(signal){ // We dont want to really kill, just stop the process @@ -1988,7 +2003,7 @@ module.exports = function setup(fsOptions) { emit("kill"); }); } - + pty.suspended = true; return; } @@ -2022,7 +2037,7 @@ module.exports = function setup(fsOptions) { var events = {}; function forwardEvent(name){ - events[name] = []; + events[name] = events[name] || []; if (isOutput && (name == "exit" || name == "close" || name == "end")) { if (name != "exit") return; @@ -2102,7 +2117,7 @@ module.exports = function setup(fsOptions) { if (session) { if (session.wait) session.wait.push(callback); - else + else if (session.pty && !session.pty.suspended) callback(null, { pty: session.pty }); } else @@ -2124,8 +2139,9 @@ module.exports = function setup(fsOptions) { var args = ["-l", "-i"]; var name = options.session || getSessionId(); - var session = { wait: [] }; + var session = sessions[name] || {}; sessions[name] = session; + if (!session.wait) session.wait = []; if (options.idle) options.command = "echo '\033[2J\033[1;1H[Idle]'"; @@ -2167,7 +2183,7 @@ module.exports = function setup(fsOptions) { if (err) return callback(err); session.pty = meta.pty = - new PtyStream(meta.pty, options.output); + new PtyStream(meta.pty, options.output, session.pty); var wait = session.wait; delete session.wait; From 00fa00256b53084cf0dbc6a71642f776840ac37b Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 6 Sep 2015 20:56:08 +0400 Subject: [PATCH 3/9] add mock meteor runner --- .../c9.fs/mock/.c9/runners/Node.js.test.run | 20 +++ plugins/c9.fs/mock/debug.js | 142 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 plugins/c9.fs/mock/.c9/runners/Node.js.test.run create mode 100644 plugins/c9.fs/mock/debug.js diff --git a/plugins/c9.fs/mock/.c9/runners/Node.js.test.run b/plugins/c9.fs/mock/.c9/runners/Node.js.test.run new file mode 100644 index 00000000..2180f667 --- /dev/null +++ b/plugins/c9.fs/mock/.c9/runners/Node.js.test.run @@ -0,0 +1,20 @@ +// This file overrides the built-in Node.js runner +// For more information see http://docs.c9.io:8080/#!/api/run-method-run +{ + "cmd": [ + "node", + "debug.js", + "1588", + "$file", + "$args" + ], + "debugger": "v8", + "debugport": 1588, + "debuggerConfig": { + "pathMap": [], + "ignoreBreak": { + "x": 1 + } + }, + "selector": "source.js" +} \ No newline at end of file diff --git a/plugins/c9.fs/mock/debug.js b/plugins/c9.fs/mock/debug.js new file mode 100644 index 00000000..74ee2ecc --- /dev/null +++ b/plugins/c9.fs/mock/debug.js @@ -0,0 +1,142 @@ +/** + * in meteor runner restarts debug process after each save. + * this emulates same sequence of events without all of the complexity of meteor + * + * add the following run config, run test.js file, write timeout value in output window + * and press enter to restart test.js after a timeout + * + * "run": { + * "@path": "/.c9/runners", + * "configs": { + * "@inited": "true", + * "json()": { + * "mock-meteor": { + * "command": "test.js", + * "debug": true, + * "name": "mock-meteor", + * "runner": "Node.js.test" + * } + * } + * } + * }, + **/ + +var net = require("net"); +var spawn = require("child_process").spawn; + +var argv = process.argv; +var port = argv[2]; +var debugPort = 5758; + +var p, interceptServer; +var outConnection = []; +var inConnection = []; +var RETRY_INTERVAL = 500; +function start() { + console.log(argv[0], ["--debug-brk=" + debugPort].concat(argv.slice(3))); + p = spawn(argv[0], ["--debug-brk=" + debugPort].concat(argv.slice(3)), {}); + p.stdout.on("data", function(e) { + process.stdout.write(e); + }); + p.stderr.on("data", function(e) { + process.stderr.write(e); + }); + + function tryConnect(port, retries, callback) { + console.log("tryConnect", retries, port); + if (!retries) + return callback(new Error("Cannot connect to port " + port)); + + var connection = net.connect(port, "localhost"); + + connection.on("connect", function() { + console.log("netproxy connected to debugger"); + connection.removeListener("error", onError); + callback(null, connection); + }); + + connection.addListener("error", onError); + function onError(e) { + if (e.code !== "ECONNREFUSED") + return callback(e); + + setTimeout(function() { + tryConnect(port, retries - 1, callback); + }, RETRY_INTERVAL); + } + } + + tryConnect(debugPort, 100, function(e, debugConnection) { + console.log("-----------------------------"); + debugConnection.on("data", function(data) { + console.log(data + ""); + if (outConnection.write) + outConnection.write(data); + else + outConnection.push(data); + }); + inConnection = debugConnection; + debugConnection.once("data", startServer); + debugConnection.on("error", function(e) { + console.log(e); + }); + }); + + outConnection = []; + inConnection = []; + + function startServer() { + interceptServer = net.createServer(function(socket) { + outConnection.forEach(function(e) {socket.write(e)}); + outConnection = socket; + socket.on("data", function(buffer) { + inConnection.write(buffer); + }); + socket.on("error", function(e) { + console.log(e); + }); + }).on("error", function(e) { + interceptServer = null; + }).listen(port); + } +} + +function stop() { + if (start.timer) clearTimeout(start.timer); + p && p.kill(); + interceptServer && interceptServer.close(); + inConnection.end && inConnection.end(); +} + +process.stdin.resume(); +process.stdin.setRawMode(true); +process.stdin.setEncoding("utf8"); +process.on('SIGINT', function() { + console.log('Got SIGINT. Press Control-D to exit.'); +}); + +process.on("SIGINT", function() { + console.log(process.argv); +}); +var buffer = ""; +process.stdin.on("data", function(s) { + process.stdout.write(s); + buffer += s; + var i = buffer.search(/\s/); + if (i == -1) return; + var t = parseInt(buffer.slice(0, i), 0); + buffer = ""; + function wait() { + console.log("killed the process, waiting" + t + "ms before restart"); + if (t > 1000) { + t -= 1000; + setTimeout(wait, 1000); + } else { + setTimeout(start, t); + } + } + wait(); + stop(); +}); +start(); +console.log(process.argv); From 12bca6963930b2b1d95ec8c6330d676868041e02 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 6 Sep 2015 23:18:33 +0400 Subject: [PATCH 4/9] restart debugger when debugged process is restarted --- package.json | 2 +- plugins/c9.fs/mock/debug.js | 16 ++++++++++++++-- plugins/c9.fs/mock/test.js | 10 ++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 453716db..5091ff44 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#5edf7086bc", + "c9.ide.run.debug": "#c2ab990dd4", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", diff --git a/plugins/c9.fs/mock/debug.js b/plugins/c9.fs/mock/debug.js index 74ee2ecc..081b7635 100644 --- a/plugins/c9.fs/mock/debug.js +++ b/plugins/c9.fs/mock/debug.js @@ -69,7 +69,7 @@ function start() { tryConnect(debugPort, 100, function(e, debugConnection) { console.log("-----------------------------"); debugConnection.on("data", function(data) { - console.log(data + ""); + console.log(data + "" + (!outConnection.write ? "" : "")); if (outConnection.write) outConnection.write(data); else @@ -82,11 +82,13 @@ function start() { }); }); - outConnection = []; + outConnection = outConnection || []; inConnection = []; function startServer() { + console.log("start-server") interceptServer = net.createServer(function(socket) { + console.log(socket) outConnection.forEach(function(e) {socket.write(e)}); outConnection = socket; socket.on("data", function(buffer) { @@ -94,9 +96,13 @@ function start() { }); socket.on("error", function(e) { console.log(e); + }) + socket.on("end", function(e) { + outConnection = null }); }).on("error", function(e) { interceptServer = null; + console.error(e); }).listen(port); } } @@ -106,6 +112,7 @@ function stop() { p && p.kill(); interceptServer && interceptServer.close(); inConnection.end && inConnection.end(); + // outConnection.end && outConnection.end(); } process.stdin.resume(); @@ -124,6 +131,11 @@ process.stdin.on("data", function(s) { buffer += s; var i = buffer.search(/\s/); if (i == -1) return; + if (/^d-out/.test(buffer)) { + console.log("end netproxy connection"); + outConnection.end && outConnection.end(); + return; + } var t = parseInt(buffer.slice(0, i), 0); buffer = ""; function wait() { diff --git a/plugins/c9.fs/mock/test.js b/plugins/c9.fs/mock/test.js index b07b88ff..558c2a2e 100644 --- a/plugins/c9.fs/mock/test.js +++ b/plugins/c9.fs/mock/test.js @@ -14,6 +14,16 @@ var Student = (function () { return Student; })(); +var options = {x: 1} +function d(a) { + var options = {x: 2} + function e(a) { + var options = {x: 2} + console.log(1) + } + e() +} +d() /** * A greeter(). */ From 6644cdcc1d5402a9a4738fa5be65e6cda3941f9d Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 7 Sep 2015 03:54:57 +0400 Subject: [PATCH 5/9] increase default max string length of v8debugger --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5091ff44..cfcb7a66 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#c2ab990dd4", + "c9.ide.run.debug": "#50226d4c8b", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", From db242d8d2ac27708c0cfdb0a5002512547ebb136 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 7 Sep 2015 22:04:53 +0000 Subject: [PATCH 6/9] restart netproxy if it stops before debugged process --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index cfcb7a66..a4644cea 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#50226d4c8b", + "c9.ide.run.debug": "#0fc0c6ae48", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", @@ -102,7 +102,7 @@ "c9.ide.recentfiles": "#7c099abf40", "c9.ide.remote": "#301d2ab519", "c9.ide.processlist": "#bc11818bb5", - "c9.ide.run": "#fd32560361", + "c9.ide.run": "#05c0054752", "c9.ide.run.build": "#0598fff697", "c9.ide.run.debug.xdebug": "#61dcbd0180", "c9.ide.save": "#e00549cb0f", From 4421ed278b6677c96fd68d517381c9a5ae01383b Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 8 Sep 2015 14:58:53 +0400 Subject: [PATCH 7/9] hide setBreakBehavior button when feature is not supported --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4644cea..1755b484 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#0fc0c6ae48", + "c9.ide.run.debug": "#23ac636255", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", From 687149ffebef4151822045717e216e9e4129404c Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 8 Sep 2015 15:01:45 +0400 Subject: [PATCH 8/9] fix pause button getting out of sync with the setting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1755b484..fd8d8016 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#23ac636255", + "c9.ide.run.debug": "#43755761eb", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4", From bd520032ad3dd140916eb735201ba7a61b0e4972 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 8 Sep 2015 19:12:23 +0400 Subject: [PATCH 9/9] show line widget for debugger exceptions --- node_modules/ace/lib/ace/line_widgets.js | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/node_modules/ace/lib/ace/line_widgets.js b/node_modules/ace/lib/ace/line_widgets.js index c1eaeb85..c8154a13 100644 --- a/node_modules/ace/lib/ace/line_widgets.js +++ b/node_modules/ace/lib/ace/line_widgets.js @@ -196,6 +196,8 @@ function LineWidgets(session) { this.session.lineWidgets[w.row] = w; + w.session = this.session; + var renderer = this.editor.renderer; if (w.html && !w.el) { w.el = dom.createElement("div"); @@ -239,6 +241,7 @@ function LineWidgets(session) { this.removeLineWidget = function(w) { w._inDocument = false; + w.session = null; if (w.el && w.el.parentNode) w.el.parentNode.removeChild(w.el); if (w.editor && w.editor.destroy) try { @@ -269,7 +272,7 @@ function LineWidgets(session) { var w = lineWidgets && lineWidgets[row]; var list = []; while (w) { - list.push(w) + list.push(w); w = w.$oldWidget; } return list; @@ -289,6 +292,7 @@ function LineWidgets(session) { for (var i = 0; i < changedWidgets.length; i++) { var w = changedWidgets[i]; if (!w || !w.el) continue; + if (w.session != this.session) continue; if (!w._inDocument) { w._inDocument = true; renderer.container.appendChild(w.el); diff --git a/package.json b/package.json index fd8d8016..fc31e3e5 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "c9.ide.find": "#35379124ca", "c9.ide.find.infiles": "#c132ad243c", "c9.ide.find.replace": "#44772dd796", - "c9.ide.run.debug": "#43755761eb", + "c9.ide.run.debug": "#e38e16e120", "c9.automate": "#47e2c429c9", "c9.ide.ace.emmet": "#6dc4585e02", "c9.ide.ace.gotoline": "#a8ff07c8f4",