script.js
* `clearBreakpoint`, `cb(...)` - Clear breakpoint
+It is also possible to set a breakpoint in a file (module) that
+isn't loaded yet:
+
+ % ./node debug test/fixtures/break-in-module/main.js
+ < debugger listening on port 5858
+ connecting to port 5858... ok
+ break in test/fixtures/break-in-module/main.js:1
+ 1 var mod = require('./mod.js');
+ 2 mod.hello();
+ 3 mod.hello();
+ debug> setBreakpoint('mod.js', 23)
+ Warning: script 'mod.js' was not loaded yet.
+ 1 var mod = require('./mod.js');
+ 2 mod.hello();
+ 3 mod.hello();
+ debug> c
+ break in test/fixtures/break-in-module/mod.js:23
+ 21
+ 22 exports.hello = function() {
+ 23 return 'hello from module';
+ 24 };
+ 25
+ debug>
+
### Info
* `backtrace`, `bt` - Print backtrace of current execution frame
scriptId = script;
}
- if (!scriptId) return this.error('Script : ' + script + ' not found');
if (ambiguous) return this.error('Script name is ambiguous');
if (line <= 0) return this.error('Line should be a positive value');
- var req = {
- type: 'scriptId',
- target: scriptId,
- line: line - 1,
- condition: condition
- };
+ var req;
+ if (scriptId) {
+ req = {
+ type: 'scriptId',
+ target: scriptId,
+ line: line - 1,
+ condition: condition
+ };
+ } else {
+ this.print('Warning: script \'' + script + '\' was not loaded yet.');
+ var escapedPath = script.replace(/([/\\.?*()^${}|[\]])/g, '\\$1');
+ var scriptPathRegex = '^(.*[\\/\\\\])?' + escapedPath + '$';
+ req = {
+ type: 'scriptRegExp',
+ target: scriptPathRegex,
+ line: line - 1,
+ condition: condition
+ };
+ }
}
self.pause();
// Try load scriptId and line from response
if (!scriptId) {
scriptId = res.script_id;
- line = res.line;
- }
-
- // If we finally have one - remember this breakpoint
- if (scriptId) {
- self.client.breakpoints.push({
- id: res.breakpoint,
- scriptId: scriptId,
- script: (self.client.scripts[scriptId] || {}).name,
- line: line,
- condition: condition
- });
+ line = res.line + 1;
}
+ // Remember this breakpoint even if scriptId is not resolved yet
+ self.client.breakpoints.push({
+ id: res.breakpoint,
+ scriptId: scriptId,
+ script: (self.client.scripts[scriptId] || {}).name,
+ line: line,
+ condition: condition,
+ scriptReq: script
+ });
}
self.resume();
});
index;
this.client.breakpoints.some(function(bp, i) {
- if (bp.scriptId === script || bp.script.indexOf(script) !== -1) {
+ if (bp.scriptId === script ||
+ bp.scriptReq === script ||
+ (bp.script && bp.script.indexOf(script) !== -1)) {
if (index !== undefined) {
ambiguous = true;
}
// Restore breakpoints
breakpoints.forEach(function(bp) {
- self.setBreakpoint(bp.scriptId, bp.line, bp.condition, true);
+ self.print('Restoring breakpoint ' + bp.scriptReq + ':' + bp.line);
+ self.setBreakpoint(bp.scriptReq, bp.line, bp.condition, true);
});
client.on('close', function() {
--- /dev/null
+var mod = require('./mod.js');
+mod.hello();
+mod.hello();
+debugger;
--- /dev/null
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+exports.hello = function() {
+ return 'hello from module';
+};
expected.push({input: input, lines: output, callback: next});
}
-var initialLines = [
+var handshakeLines = [
/listening on port \d+/,
- /connecting.* ok/,
+ /connecting.* ok/
+];
+
+var initialBreakLines = [
/break in .*:1/,
/1/, /2/, /3/
];
+var initialLines = handshakeLines.concat(initialBreakLines);
+
// Process initial lines
addTest(null, initialLines);
exports.startDebugger = startDebugger;
exports.addTest = addTest;
exports.initialLines = initialLines;
+exports.handshakeLines = handshakeLines;
+exports.initialBreakLines = initialBreakLines;
--- /dev/null
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var repl = require('./helper-debugger-repl.js');
+
+repl.startDebugger('break-in-module/main.js');
+
+// -- SET BREAKPOINT --
+
+// Set breakpoint by file name + line number where the file is not loaded yet
+repl.addTest('sb("mod.js", 23)', [
+ /Warning: script 'mod\.js' was not loaded yet\./,
+ /1/, /2/, /3/, /4/, /5/, /6/
+]);
+
+// Check escaping of regex characters
+repl.addTest('sb(")^$*+?}{|][(.js\\\\", 1)', [
+ /Warning: script '[^']+' was not loaded yet\./,
+ /1/, /2/, /3/, /4/, /5/, /6/
+]);
+
+// continue - the breakpoint should be triggered
+repl.addTest('c', [
+ /break in .*[\\\/]mod\.js:23/,
+ /21/, /22/, /23/, /24/, /25/
+]);
+
+// -- RESTORE BREAKPOINT ON RESTART --
+
+// Restart the application - breakpoint should be restored
+repl.addTest('restart', [].concat(
+ [
+ /terminated/
+ ],
+ repl.handshakeLines,
+ [
+ /Restoring breakpoint mod.js:23/,
+ /Warning: script 'mod\.js' was not loaded yet\./,
+ /Restoring breakpoint \).*:\d+/,
+ /Warning: script '\)[^']*' was not loaded yet\./
+ ],
+ repl.initialBreakLines));
+
+// continue - the breakpoint should be triggered
+repl.addTest('c', [
+ /break in .*[\\\/]mod\.js:23/,
+ /21/, /22/, /23/, /24/, /25/
+]);
+
+// -- CLEAR BREAKPOINT SET IN MODULE TO BE LOADED --
+
+repl.addTest('cb("mod.js", 23)', [
+ /18/, /./, /./, /./, /./, /./, /./, /./, /26/
+]);
+
+repl.addTest('c', [
+ /break in .*[\\\/]main\.js:4/,
+ /2/, /3/, /4/, /5/, /6/
+]);
+
+// -- (END) --
+repl.addTest('quit', []);