123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- var convert = require('./convert'),
- CallFramesProvider = require('./CallFramesProvider').CallFramesProvider;
- /**
- * @param {Object} config
- * @param {FrontendClient} frontendClient
- * @param {DebuggerClient} debuggerClient
- * @param {ScriptManager} scriptManager
- * @constructor
- */
- function BreakEventHandler(config, frontendClient, debuggerClient, scriptManager) {
- this._config = config;
- this._frontendClient = frontendClient;
- this._debuggerClient = debuggerClient;
- this._scriptManager = scriptManager;
- this._callFramesProvider = new CallFramesProvider(config, debuggerClient);
- this._registerDebuggerEventHandlers();
- }
- var callbackForNextBreak;
- Object.defineProperties(BreakEventHandler.prototype, {
- /** @type {Number} */
- continueToLocationBreakpointId: {
- writable: true,
- value: null
- },
- /** @type {function(eventData)} */
- callbackForNextBreak: {
- get: function() { return callbackForNextBreak; },
- set: function(value) {
- if (value && callbackForNextBreak)
- throw new Error('Cannot set multiple callbacks for the next break.');
- callbackForNextBreak = value;
- }
- }
- });
- BreakEventHandler.prototype._registerDebuggerEventHandlers = function() {
- this._debuggerClient.on('break', this._onBreak.bind(this));
- this._debuggerClient.on('exception', this._onBreak.bind(this));
- };
- BreakEventHandler.prototype._onBreak = function(obj) {
- var scriptId = obj.script.id,
- hitBreakpoints = obj.breakpoints,
- source = this._scriptManager.findScriptByID(scriptId);
- // Source is undefined when the breakpoint was in code eval()-ed via
- // console or eval()-ed internally by node inspector.
- // We could send backtrace in such case, but that isn't working well now.
- // V8 is reusing the same scriptId for multiple eval() calls and DevTools
- // front-end does not update the displayed source code when a content
- // of a script changes.
- // The following solution - ignore the breakpoint and resume the
- // execution - should be good enough in most cases.
- if (!source || source.hidden) {
- this._debuggerClient.request('continue', { stepaction: 'out' });
- return;
- }
- if (this.callbackForNextBreak) {
- var callback = this.callbackForNextBreak;
- this.callbackForNextBreak = null;
- callback(obj);
- return;
- }
- if (this.continueToLocationBreakpointId !== null) {
- this._debuggerClient.clearBreakpoint(
- this.continueToLocationBreakpointId,
- function(err, result) {
- if (err)
- this._frontendClient.sendLogToConsole('warning', err);
- else
- this.continueToLocationBreakpointId = null;
- }.bind(this)
- );
- }
- this.sendBacktraceToFrontend(obj.exception, hitBreakpoints);
- };
- /**
- * @param {function(error, response)} callback
- */
- BreakEventHandler.prototype.fetchCallFrames = function(callback) {
- this._callFramesProvider.fetchCallFrames(callback);
- };
- /**
- * @param {Object} exception
- * @param {Array.<number>} hitBreakpoints
- */
- BreakEventHandler.prototype.sendBacktraceToFrontend = function(exception, hitBreakpoints) {
- this.fetchCallFrames(function(error, result) {
- if (error)
- this._frontendClient.sendLogToConsole('error', error);
- else
- this._frontendClient.sendEvent(
- 'Debugger.paused',
- {
- callFrames: result,
- reason: exception ? 'exception' : 'other',
- data: exception ? convert.v8RefToInspectorObject(exception) : null,
- hitBreakpoints: hitBreakpoints
- });
- }.bind(this));
- };
- exports.BreakEventHandler = BreakEventHandler;
|