Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js

Issue 177049: On Linux, move the passing of filedescriptors to a dedicated socketpair(). (Closed)
Patch Set: Removed *.d files from reference build Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
index 890f7046dfb41b730068cd1bf8d25d8f1db1fad5..b977c0bb397404b58bf5dff8b5502b7b0111fb8b 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
@@ -15,12 +15,12 @@ goog.provide('devtools.DebuggerAgent');
devtools.DebuggerAgent = function() {
RemoteDebuggerAgent.DebuggerOutput =
goog.bind(this.handleDebuggerOutput_, this);
- RemoteDebuggerAgent.DidGetContextId =
- goog.bind(this.didGetContextId_, this);
- RemoteDebuggerAgent.DidIsProfilingStarted =
- goog.bind(this.didIsProfilingStarted_, this);
- RemoteDebuggerAgent.DidGetLogLines =
- goog.bind(this.didGetLogLines_, this);
+ RemoteDebuggerAgent.SetContextId =
+ goog.bind(this.setContextId_, this);
+ RemoteDebuggerAgent.DidGetActiveProfilerModules =
+ goog.bind(this.didGetActiveProfilerModules_, this);
+ RemoteDebuggerAgent.DidGetNextLogLines =
+ goog.bind(this.didGetNextLogLines_, this);
/**
* Id of the inspected page global context. It is used for filtering scripts.
@@ -44,11 +44,10 @@ devtools.DebuggerAgent = function() {
this.requestNumberToBreakpointInfo_ = null;
/**
- * Information on current stack top frame.
- * See JavaScriptCallFrame.idl.
- * @type {?devtools.CallFrame}
+ * Information on current stack frames.
+ * @type {Array.<devtools.CallFrame>}
*/
- this.currentCallFrame_ = null;
+ this.callFrames_ = [];
/**
* Whether to stop in the debugger on the exceptions.
@@ -69,23 +68,64 @@ devtools.DebuggerAgent = function() {
this.scriptsCacheInitialized_ = false;
/**
- * Whether user has stopped profiling and we are retrieving the rest of
- * profiler's log.
- * @type {boolean}
- */
- this.isProcessingProfile_ = false;
-
- /**
- * The position in log file to read from.
+ * Active profiler modules flags.
* @type {number}
*/
- this.lastProfileLogPosition_ = 0;
+ this.activeProfilerModules_ =
+ devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE;
/**
* Profiler processor instance.
* @type {devtools.profiler.Processor}
*/
this.profilerProcessor_ = new devtools.profiler.Processor();
+
+ /**
+ * Container of all breakpoints set using resource URL. These breakpoints
+ * survive page reload. Breakpoints set by script id(for scripts that don't
+ * have URLs) are stored in ScriptInfo objects.
+ * @type {Object}
+ */
+ this.urlToBreakpoints_ = {};
+
+
+ /**
+ * Exception message that is shown to user while on exception break.
+ * @type {WebInspector.ConsoleMessage}
+ */
+ this.currentExceptionMessage_ = null;
+};
+
+
+/**
+ * A copy of the scope types from v8/src/mirror-delay.js
+ * @enum {number}
+ */
+devtools.DebuggerAgent.ScopeType = {
+ Global: 0,
+ Local: 1,
+ With: 2,
+ Closure: 3
+};
+
+
+/**
+ * A no-op JS expression that is sent to the inspected page in order to force v8
+ * execution.
+ */
+devtools.DebuggerAgent.VOID_SCRIPT = 'javascript:void(0)';
+
+
+/**
+ * A copy of enum from include/v8.h
+ * @enum {number}
+ */
+devtools.DebuggerAgent.ProfilerModules = {
+ PROFILER_MODULE_NONE: 0,
+ PROFILER_MODULE_CPU: 1,
+ PROFILER_MODULE_HEAP_STATS: 1 << 1,
+ PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2,
+ PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16
};
@@ -93,42 +133,45 @@ devtools.DebuggerAgent = function() {
* Resets debugger agent to its initial state.
*/
devtools.DebuggerAgent.prototype.reset = function() {
- this.scriptsCacheInitialized_ = false;
this.contextId_ = null;
this.parsedScripts_ = {};
this.requestNumberToBreakpointInfo_ = {};
- this.currentCallFrame_ = null;
+ this.callFrames_ = [];
this.requestSeqToCallback_ = {};
+
+ // Profiler isn't reset because it contains no data that is
+ // specific for a particular V8 instance. All such data is
+ // managed by an agent on the Render's side.
};
/**
- * Requests scripts list if it has not been requested yet.
+ * Initializes scripts UI. Asynchronously requests for all parsed scripts
+ * if necessary. Response will be processed in handleScriptsResponse_.
*/
-devtools.DebuggerAgent.prototype.initializeScriptsCache = function() {
- if (!this.scriptsCacheInitialized_) {
- this.scriptsCacheInitialized_ = true;
- this.requestScripts();
+devtools.DebuggerAgent.prototype.initUI = function() {
+ // There can be a number of scripts from after-compile events that are
+ // pending addition into the UI.
+ for (var scriptId in this.parsedScripts_) {
+ var script = this.parsedScripts_[scriptId];
+ WebInspector.parsedScriptSource(scriptId, script.getUrl(),
+ undefined /* script source */, script.getLineOffset());
}
-};
-
-/**
- * Asynchronously requests for all parsed script sources. Response will be
- * processed in handleScriptsResponse_.
- */
-devtools.DebuggerAgent.prototype.requestScripts = function() {
- if (this.contextId_ === null) {
- // Update context id first to filter the scripts.
- RemoteDebuggerAgent.GetContextId();
+ if (this.contextId_) {
+ // We already have context id. This means that we are here from the
+ // very beginning of the page load cycle and hence will get all scripts
+ // via after-compile events. No need to request scripts for this session.
return;
}
+
+ RemoteDebuggerAgent.GetContextId();
var cmd = new devtools.DebugCommand('scripts', {
'includeSource': false
});
devtools.DebuggerAgent.sendCommand_(cmd);
// Force v8 execution so that it gets to processing the requested command.
- devtools.tools.evaluateJavaScript('javascript:void(0)');
+ devtools.tools.evaluateJavaScript(devtools.DebuggerAgent.VOID_SCRIPT);
};
@@ -142,7 +185,7 @@ devtools.DebuggerAgent.prototype.requestScripts = function() {
devtools.DebuggerAgent.prototype.resolveScriptSource = function(
scriptId, callback) {
var script = this.parsedScripts_[scriptId];
- if (!script) {
+ if (!script || script.isUnresolved()) {
callback(null);
return;
}
@@ -153,7 +196,7 @@ devtools.DebuggerAgent.prototype.resolveScriptSource = function(
});
devtools.DebuggerAgent.sendCommand_(cmd);
// Force v8 execution so that it gets to processing the requested command.
- devtools.tools.evaluateJavaScript('javascript:void(0)');
+ devtools.tools.evaluateJavaScript(devtools.DebuggerAgent.VOID_SCRIPT);
this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
if (msg.isSuccess()) {
@@ -186,19 +229,44 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) {
line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
- var breakpointInfo = script.getBreakpointInfo(line);
- if (breakpointInfo) {
- return;
- }
+ var commandArguments;
+ if (script.getUrl()) {
+ var breakpoints = this.urlToBreakpoints_[script.getUrl()];
+ if (breakpoints && breakpoints[line]) {
+ return;
+ }
+ if (!breakpoints) {
+ breakpoints = {};
+ this.urlToBreakpoints_[script.getUrl()] = breakpoints;
+ }
- breakpointInfo = new devtools.BreakpointInfo(sourceId, line);
- script.addBreakpointInfo(breakpointInfo);
+ var breakpointInfo = new devtools.BreakpointInfo(line);
+ breakpoints[line] = breakpointInfo;
- var cmd = new devtools.DebugCommand('setbreakpoint', {
- 'type': 'scriptId',
- 'target': sourceId,
- 'line': line
- });
+ commandArguments = {
+ 'groupId': this.contextId_,
+ 'type': 'script',
+ 'target': script.getUrl(),
+ 'line': line
+ };
+ } else {
+ var breakpointInfo = script.getBreakpointInfo(line);
+ if (breakpointInfo) {
+ return;
+ }
+
+ breakpointInfo = new devtools.BreakpointInfo(line);
+ script.addBreakpointInfo(breakpointInfo);
+
+ commandArguments = {
+ 'groupId': this.contextId_,
+ 'type': 'scriptId',
+ 'target': sourceId,
+ 'line': line
+ };
+ }
+
+ var cmd = new devtools.DebugCommand('setbreakpoint', commandArguments);
this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo;
@@ -218,8 +286,22 @@ devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) {
line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
- var breakpointInfo = script.getBreakpointInfo(line);
- script.removeBreakpointInfo(breakpointInfo);
+ var breakpointInfo;
+ if (script.getUrl()) {
+ var breakpoints = this.urlToBreakpoints_[script.getUrl()];
+ breakpointInfo = breakpoints[line];
+ delete breakpoints[line];
+ } else {
+ breakpointInfo = script.getBreakpointInfo(line);
+ if (breakpointInfo) {
+ script.removeBreakpointInfo(breakpointInfo);
+ }
+ }
+
+ if (!breakpointInfo) {
+ return;
+ }
+
breakpointInfo.markAsRemoved();
var id = breakpointInfo.getV8Id();
@@ -262,12 +344,71 @@ devtools.DebuggerAgent.prototype.stepOverStatement = function() {
* breakpoint or an exception.
*/
devtools.DebuggerAgent.prototype.resumeExecution = function() {
+ this.clearExceptionMessage_();
var cmd = new devtools.DebugCommand('continue');
devtools.DebuggerAgent.sendCommand_(cmd);
};
/**
+ * Creates exception message and schedules it for addition to the resource upon
+ * backtrace availability.
+ * @param {string} url Resource url.
+ * @param {number} line Resource line number.
+ * @param {string} message Exception text.
+ */
+devtools.DebuggerAgent.prototype.createExceptionMessage_ = function(
+ url, line, message) {
+ this.currentExceptionMessage_ = new WebInspector.ConsoleMessage(
+ WebInspector.ConsoleMessage.MessageSource.JS,
+ WebInspector.ConsoleMessage.MessageType.Log,
+ WebInspector.ConsoleMessage.MessageLevel.Error,
+ line,
+ url,
+ 0 /* group level */,
+ 1 /* repeat count */,
+ '[Exception] ' + message);
+};
+
+
+/**
+ * Shows pending exception message that is created with createExceptionMessage_
+ * earlier.
+ */
+devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() {
+ if (!this.currentExceptionMessage_) {
+ return;
+ }
+ var msg = this.currentExceptionMessage_;
+ var resource = WebInspector.resourceURLMap[msg.url];
+ if (resource) {
+ msg.resource = resource;
+ WebInspector.panels.resources.addMessageToResource(resource, msg);
+ } else {
+ this.currentExceptionMessage_ = null;
+ }
+};
+
+
+/**
+ * Clears exception message from the resource.
+ */
+devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() {
+ if (this.currentExceptionMessage_) {
+ var messageElement =
+ this.currentExceptionMessage_._resourceMessageLineElement;
+ var bubble = messageElement.parentElement;
+ bubble.removeChild(messageElement);
+ if (!bubble.firstChild) {
+ // Last message in bubble removed.
+ bubble.parentElement.removeChild(bubble);
+ }
+ this.currentExceptionMessage_ = null;
+ }
+};
+
+
+/**
* @return {boolean} True iff the debugger will pause execution on the
* exceptions.
*/
@@ -287,15 +428,6 @@ devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) {
/**
- * Current stack top frame.
- * @return {devtools.CallFrame}
- */
-devtools.DebuggerAgent.prototype.getCurrentCallFrame = function() {
- return this.currentCallFrame_;
-};
-
-
-/**
* Sends 'evaluate' request to the debugger.
* @param {Object} arguments Request arguments map.
* @param {function(devtools.DebuggerMessage)} callback Callback to be called
@@ -316,53 +448,131 @@ devtools.DebuggerAgent.prototype.requestEvaluate = function(
* @param {Object} object Object whose properties should be resolved.
* @param {function(devtools.DebuggerMessage)} Callback to be called when all
* children are resolved.
- */
-devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback) {
- if ('ref' in object) {
+ * @param {boolean} noIntrinsic Whether intrinsic properties should be included.
+ */
+devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback,
+ noIntrinsic) {
+ if ('handle' in object) {
+ var result = [];
+ devtools.DebuggerAgent.formatObjectProperties_(object, result,
+ noIntrinsic);
+ callback(result);
+ } else {
this.requestLookup_([object.ref], function(msg) {
- var result = {};
+ var result = [];
if (msg.isSuccess()) {
var handleToObject = msg.getBody();
var resolved = handleToObject[object.ref];
- devtools.DebuggerAgent.formatObjectProperties_(resolved, result);
+ devtools.DebuggerAgent.formatObjectProperties_(resolved, result,
+ noIntrinsic);
+ callback(result);
} else {
- result.error = 'Failed to resolve children: ' + msg.getMessage();
+ callback([]);
}
- object.resolvedValue = result;
- callback(object);
});
+ }
+};
- return;
- } else {
- if (!object.resolvedValue) {
- var message = 'Corrupted object: ' + JSON.stringify(object);
- object.resolvedValue = {};
- object.resolvedValue.error = message;
+
+/**
+ * Sends 'scope' request for the scope object to resolve its variables.
+ * @param {Object} scope Scope to be resolved.
+ * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback
+ * Callback to be called when all scope variables are resolved.
+ */
+devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) {
+ var cmd = new devtools.DebugCommand('scope', {
+ 'frameNumber': scope.frameNumber,
+ 'number': scope.index,
+ 'compactFormat': true
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
+ var result = [];
+ if (msg.isSuccess()) {
+ var scopeObjectJson = msg.getBody().object;
+ devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result,
+ true /* no intrinsic */);
}
- callback(object);
- }
+ callback(result);
+ };
};
/**
- * Starts (resumes) profiling.
+ * Sets up callbacks that deal with profiles processing.
*/
-devtools.DebuggerAgent.prototype.startProfiling = function() {
- if (this.isProcessingProfile_) {
- return;
+devtools.DebuggerAgent.prototype.setupProfilerProcessorCallbacks = function() {
+ // A temporary icon indicating that the profile is being processed.
+ var processingIcon = new WebInspector.SidebarTreeElement(
+ 'profile-sidebar-tree-item',
+ WebInspector.UIString('Processing...'),
+ '', null, false);
+ var profilesSidebar = WebInspector.panels.profiles.sidebarTree;
+
+ this.profilerProcessor_.setCallbacks(
+ function onProfileProcessingStarted() {
+ // Set visually empty string. Subtitle hiding is done via styles
+ // manipulation which doesn't play well with dynamic append / removal.
+ processingIcon.subtitle = ' ';
+ profilesSidebar.appendChild(processingIcon);
+ },
+ function onProfileProcessingStatus(ticksCount) {
+ processingIcon.subtitle =
+ WebInspector.UIString('%d ticks processed', ticksCount);
+ },
+ function onProfileProcessingFinished(profile) {
+ profilesSidebar.removeChild(processingIcon);
+ WebInspector.addProfile(profile);
+ // If no profile is currently shown, show the new one.
+ var profilesPanel = WebInspector.panels.profiles;
+ if (!profilesPanel.visibleView) {
+ profilesPanel.showProfile(profile);
+ }
+ }
+ );
+};
+
+
+/**
+ * Initializes profiling state.
+ */
+devtools.DebuggerAgent.prototype.initializeProfiling = function() {
+ this.setupProfilerProcessorCallbacks();
+ RemoteDebuggerAgent.GetActiveProfilerModules();
+};
+
+
+/**
+ * Starts profiling.
+ * @param {number} modules List of modules to enable.
+ */
+devtools.DebuggerAgent.prototype.startProfiling = function(modules) {
+ RemoteDebuggerAgent.StartProfiling(modules);
+ if (modules &
+ devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
+ // Active modules will not change, instead, a snapshot will be logged.
+ RemoteDebuggerAgent.GetNextLogLines();
+ } else {
+ RemoteDebuggerAgent.GetActiveProfilerModules();
}
- RemoteDebuggerAgent.StartProfiling();
- // Query if profiling has been really started.
- RemoteDebuggerAgent.IsProfilingStarted();
};
/**
- * Stops (pauses) profiling.
+ * Stops profiling.
+ */
+devtools.DebuggerAgent.prototype.stopProfiling = function(modules) {
+ RemoteDebuggerAgent.StopProfiling(modules);
+};
+
+
+/**
+ * @param{number} scriptId
+ * @return {string} Type of the context of the script with specified id.
*/
-devtools.DebuggerAgent.prototype.stopProfiling = function() {
- this.isProcessingProfile_ = true;
- RemoteDebuggerAgent.StopProfiling();
+devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) {
+ return this.parsedScripts_[scriptId].getContextType();
};
@@ -404,6 +614,7 @@ devtools.DebuggerAgent.sendCommand_ = function(cmd) {
* @param {string} action 'in', 'out' or 'next' action.
*/
devtools.DebuggerAgent.prototype.stepCommand_ = function(action) {
+ this.clearExceptionMessage_();
var cmd = new devtools.DebugCommand('continue', {
'stepaction': action,
'stepcount': 1
@@ -427,13 +638,11 @@ devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) {
/**
- * Handles GetContextId response.
+ * Sets debugger context id for scripts filtering.
* @param {number} contextId Id of the inspected page global context.
*/
-devtools.DebuggerAgent.prototype.didGetContextId_ = function(contextId) {
+devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) {
this.contextId_ = contextId;
- // Update scripts.
- this.requestScripts();
};
@@ -452,7 +661,6 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) {
throw e;
}
-
if (msg.getType() == 'event') {
if (msg.getEvent() == 'break') {
this.handleBreakEvent_(msg);
@@ -474,6 +682,8 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) {
this.invokeCallbackForResponse_(msg);
} else if (msg.getCommand() == 'evaluate') {
this.invokeCallbackForResponse_(msg);
+ } else if (msg.getCommand() == 'scope') {
+ this.invokeCallbackForResponse_(msg);
}
}
};
@@ -483,13 +693,12 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) {
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) {
+ // Force scrips panel to be shown first.
+ WebInspector.currentPanel = WebInspector.panels.scripts;
+
var body = msg.getBody();
var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
- this.currentCallFrame_ = new devtools.CallFrame();
- this.currentCallFrame_.sourceID = body.script.id;
- this.currentCallFrame_.line = line;
- this.currentCallFrame_.script = body.script;
this.requestBacktrace_();
};
@@ -498,24 +707,14 @@ devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) {
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) {
+ // Force scrips panel to be shown first.
+ WebInspector.currentPanel = WebInspector.panels.scripts;
+
var body = msg.getBody();
- debugPrint('Uncaught exception in ' + body.script.name + ':' +
- body.sourceLine + '\n' + body.sourceLineText);
if (this.pauseOnExceptions_) {
var body = msg.getBody();
-
- var sourceId = -1;
- // The exception may happen in native code in which case there is no script.
- if (body.script) {
- sourceId = body.script.id;
- }
-
var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
-
- this.currentCallFrame_ = new devtools.CallFrame();
- this.currentCallFrame_.sourceID = sourceId;
- this.currentCallFrame_.line = line;
- this.currentCallFrame_.script = body.script;
+ this.createExceptionMessage_(body.script.name, line, body.exception.text);
this.requestBacktrace_();
} else {
this.resumeExecution();
@@ -540,11 +739,16 @@ devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) {
continue;
}
+ // There is no script source
+ if (this.isVoidScript_(script)) {
+ continue;
+ }
+
// We may already have received the info in an afterCompile event.
if (script.id in this.parsedScripts_) {
continue;
}
- this.addScriptInfo_(script);
+ this.addScriptInfo_(script, msg);
}
};
@@ -567,7 +771,7 @@ devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(
if (this.contextId_ === null) {
return true;
}
- return (scriptContextId == this.contextId_);
+ return (scriptContextId.value == this.contextId_);
};
@@ -599,47 +803,73 @@ devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) {
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) {
+ if (!this.contextId_) {
+ // Ignore scripts delta if main request has not been issued yet.
+ return;
+ }
var script = msg.getBody().script;
+
+ if (this.isVoidScript_(script)) {
+ return;
+ }
+
// Ignore scripts from other tabs.
if (!this.isScriptFromInspectedContext_(script, msg)) {
return;
}
- this.addScriptInfo_(script);
+ this.addScriptInfo_(script, msg);
};
/**
- * Handles current profiler status.
+ * @param {Object} script Parsed JSON object representing script.
+ * @return {boolean} Whether the script is a result of the void script
+ * evaluation and should not appear in the UI.
*/
-devtools.DebuggerAgent.prototype.didIsProfilingStarted_ = function(
- is_started) {
- if (is_started) {
+devtools.DebuggerAgent.prototype.isVoidScript_ = function(script) {
+ return !script.name &&
+ (script.sourceStart == devtools.DebuggerAgent.VOID_SCRIPT ||
+ script.source == devtools.DebuggerAgent.VOID_SCRIPT);
+};
+
+
+/**
+ * Handles current profiler status.
+ * @param {number} modules List of active (started) modules.
+ */
+devtools.DebuggerAgent.prototype.didGetActiveProfilerModules_ = function(
+ modules) {
+ var profModules = devtools.DebuggerAgent.ProfilerModules;
+ var profModuleNone = profModules.PROFILER_MODULE_NONE;
+ if (modules != profModuleNone &&
+ this.activeProfilerModules_ == profModuleNone) {
// Start to query log data.
- RemoteDebuggerAgent.GetLogLines(this.lastProfileLogPosition_);
+ RemoteDebuggerAgent.GetNextLogLines();
+ }
+ this.activeProfilerModules_ = modules;
+ // Update buttons.
+ WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU);
+ if (modules != profModuleNone) {
+ // Monitor profiler state. It can stop itself on buffer fill-up.
+ setTimeout(
+ function() { RemoteDebuggerAgent.GetActiveProfilerModules(); }, 1000);
}
- WebInspector.setRecordingProfile(is_started);
};
/**
- * Handles a portion of a profiler log retrieved by GetLogLines call.
+ * Handles a portion of a profiler log retrieved by GetNextLogLines call.
* @param {string} log A portion of profiler log.
- * @param {number} newPosition The position in log file to read from
- * next time.
*/
-devtools.DebuggerAgent.prototype.didGetLogLines_ = function(
- log, newPosition) {
+devtools.DebuggerAgent.prototype.didGetNextLogLines_ = function(log) {
if (log.length > 0) {
this.profilerProcessor_.processLogChunk(log);
- this.lastProfileLogPosition_ = newPosition;
- } else if (this.isProcessingProfile_) {
- this.isProcessingProfile_ = false;
- WebInspector.setRecordingProfile(false);
- WebInspector.addProfile(this.profilerProcessor_.createProfileForView());
+ } else if (this.activeProfilerModules_ ==
+ devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE) {
+ // No new data and profiling is stopped---suspend log reading.
return;
}
- setTimeout(function() { RemoteDebuggerAgent.GetLogLines(newPosition); },
- this.isProcessingProfile_ ? 100 : 1000);
+ setTimeout(function() { RemoteDebuggerAgent.GetNextLogLines(); }, 500);
};
@@ -647,12 +877,19 @@ devtools.DebuggerAgent.prototype.didGetLogLines_ = function(
* Adds the script info to the local cache. This method assumes that the script
* is not in the cache yet.
* @param {Object} script Script json object from the debugger message.
+ * @param {devtools.DebuggerMessage} msg Debugger message containing the script
+ * data.
*/
-devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script) {
+devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) {
+ var context = msg.lookup(script.context.ref);
+ var contextType = context.data.type;
this.parsedScripts_[script.id] = new devtools.ScriptInfo(
- script.id, script.lineOffset);
- WebInspector.parsedScriptSource(
- script.id, script.name, script.source, script.lineOffset);
+ script.id, script.name, script.lineOffset, contextType);
+ if (WebInspector.panels.scripts.element.parentElement) {
+ // Only report script as parsed after scripts panel has been shown.
+ WebInspector.parsedScriptSource(
+ script.id, script.name, script.source, script.lineOffset);
+ }
};
@@ -670,27 +907,32 @@ devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function(
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) {
- if (!this.currentCallFrame_) {
- return;
+ var frames = msg.getBody().frames;
+ this.callFrames_ = [];
+ for (var i = 0; i < frames.length; ++i) {
+ this.callFrames_.push(this.formatCallFrame_(frames[i]));
}
+ WebInspector.pausedScript(this.callFrames_);
+ this.showPendingExceptionMessage_();
+ DevToolsHost.activateWindow();
+};
- var script = this.currentCallFrame_.script;
- var callerFrame = null;
- var f = null;
- var frames = msg.getBody().frames;
- for (var i = frames.length - 1; i>=0; i--) {
- var nextFrame = frames[i];
- var f = devtools.DebuggerAgent.formatCallFrame_(nextFrame, script, msg);
- f.frameNumber = i;
- f.caller = callerFrame;
- callerFrame = f;
- }
+/**
+ * Returns current suspended stack.
+ */
+devtools.DebuggerAgent.prototype.getCallFrames = function(callback) {
+ return this.callFrames_;
+};
- this.currentCallFrame_ = f;
- WebInspector.pausedScript();
- DevToolsHost.activateWindow();
+/**
+ * Evaluates code on given callframe.
+ */
+devtools.DebuggerAgent.prototype.evaluateInCallFrame = function(
+ callFrameId, code, callback) {
+ var callFrame = this.callFrames_[callFrameId];
+ callFrame.evaluate_(code, callback);
};
@@ -712,103 +954,101 @@ devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) {
};
-devtools.DebuggerAgent.prototype.evaluateInCallFrame_ = function(expression) {
-};
-
-
/**
* @param {Object} stackFrame Frame json object from 'backtrace' response.
- * @param {Object} script Script json object from 'break' event.
- * @param {devtools.DebuggerMessage} msg Parsed 'backtrace' response.
* @return {!devtools.CallFrame} Object containing information related to the
* call frame in the format expected by ScriptsPanel and its panes.
*/
-devtools.DebuggerAgent.formatCallFrame_ = function(stackFrame, script, msg) {
- var sourceId = script.id;
-
+devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) {
var func = stackFrame.func;
var sourceId = func.scriptId;
- var funcName = func.name || func.inferredName || '(anonymous function)';
- var scope = {};
-
- // Add arguments.
- devtools.DebuggerAgent.argumentsArrayToMap_(stackFrame.arguments, scope);
-
- // Add local variables.
- devtools.DebuggerAgent.propertiesToMap_(stackFrame.locals, scope);
-
- var thisObject = devtools.DebuggerAgent.formatObjectReference_(
- stackFrame.receiver);
- // Add variable with name 'this' to the scope.
- scope['this'] = thisObject;
+ // Add service script if it does not exist.
+ var existingScript = this.parsedScripts_[sourceId];
+ if (!existingScript) {
+ this.parsedScripts_[sourceId] = new devtools.ScriptInfo(
+ sourceId, null /* name */, 0 /* line */, 'unknown' /* type */,
+ true /* unresolved */);
+ WebInspector.parsedScriptSource(sourceId, null, null, 0);
+ }
+ var funcName = func.name || func.inferredName || '(anonymous function)';
var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line);
- var result = new devtools.CallFrame();
- result.sourceID = sourceId;
- result.line = line;
- result.type = 'function';
- result.functionName = funcName;
- result.localScope = scope;
- result.scopeChain = [scope];
- result.thisObject = thisObject;
- return result;
+
+ // Add basic scope chain info with scope variables.
+ var scopeChain = [];
+ var ScopeType = devtools.DebuggerAgent.ScopeType;
+ for (var i = 0; i < stackFrame.scopes.length; i++) {
+ var scope = stackFrame.scopes[i];
+ scope.frameNumber = stackFrame.index;
+ var scopeObjectProxy = new WebInspector.ObjectProxy(scope, [], 0, '', true);
+ scopeObjectProxy.isScope = true;
+ scopeObjectProxy.properties = {}; // TODO(pfeldman): Fix autocomplete.
+ switch(scope.type) {
+ case ScopeType.Global:
+ scopeObjectProxy.isDocument = true;
+ break;
+ case ScopeType.Local:
+ scopeObjectProxy.isLocal = true;
+ scopeObjectProxy.thisObject =
+ devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver);
+ break;
+ case ScopeType.With:
+ scopeObjectProxy.isWithBlock = true;
+ break;
+ case ScopeType.Closure:
+ scopeObjectProxy.isClosure = true;
+ break;
+ }
+ scopeChain.push(scopeObjectProxy);
+ }
+ return new devtools.CallFrame(stackFrame.index, 'function', funcName,
+ sourceId, line, scopeChain);
};
/**
* Collects properties for an object from the debugger response.
* @param {Object} object An object from the debugger protocol response.
- * @param {Object} result A map to put the properties in.
- */
-devtools.DebuggerAgent.formatObjectProperties_ = function(object, result) {
- devtools.DebuggerAgent.propertiesToMap_(object.properties, result);
- result.protoObject = devtools.DebuggerAgent.formatObjectReference_(
- object.protoObject);
- result.prototypeObject = devtools.DebuggerAgent.formatObjectReference_(
- object.prototypeObject);
- result.constructorFunction = devtools.DebuggerAgent.formatObjectReference_(
- object.constructorFunction);
+ * @param {Array.<WebInspector.ObjectPropertyProxy>} result An array to put the
+ * properties into.
+ * @param {boolean} noIntrinsic Whether intrinsic properties should be
+ * included.
+ */
+devtools.DebuggerAgent.formatObjectProperties_ = function(object, result,
+ noIntrinsic) {
+ devtools.DebuggerAgent.propertiesToProxies_(object.properties, result);
+ if (noIntrinsic) {
+ return;
+ }
+
+ result.push(new WebInspector.ObjectPropertyProxy('__proto__',
+ devtools.DebuggerAgent.formatObjectProxy_(object.protoObject)));
+ result.push(new WebInspector.ObjectPropertyProxy('prototype',
+ devtools.DebuggerAgent.formatObjectProxy_(object.prototypeObject)));
+ result.push(new WebInspector.ObjectPropertyProxy('constructor',
+ devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction)));
};
/**
- * For each property in 'properties' puts its name and user-friendly value into
- * 'map'.
+ * For each property in 'properties' creates its proxy representative.
* @param {Array.<Object>} properties Receiver properties or locals array from
* 'backtrace' response.
- * @param {Object} map Result holder.
- */
-devtools.DebuggerAgent.propertiesToMap_ = function(properties, map) {
- for (var j = 0; j < properties.length; j++) {
- var nextValue = properties[j];
- // Skip unnamed properties. They may appear e.g. when number of actual
- // parameters is greater the that of formal. In that case the superfluous
- // parameters will be present in the arguments list as elements without
- // names.
- if (nextValue.name) {
- map[nextValue.name] =
- devtools.DebuggerAgent.formatObjectReference_(nextValue.value);
+ * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder.
+ */
+devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) {
+ var map = {};
+ for (var i = 0; i < properties.length; ++i) {
+ var property = properties[i];
+ var name = String(property.name);
+ if (name in map) {
+ continue;
}
- }
-};
-
-
-/**
- * Puts arguments from the protocol arguments array to the map assigning names
- * to the anonymous arguments.
- * @param {Array.<Object>} array Arguments array from 'backtrace' response.
- * @param {Object} map Result holder.
- */
-devtools.DebuggerAgent.argumentsArrayToMap_ = function(array, map) {
- for (var j = 0; j < array.length; j++) {
- var nextValue = array[j];
- // Skip unnamed properties. They may appear e.g. when number of actual
- // parameters is greater the that of formal. In that case the superfluous
- // parameters will be present in the arguments list as elements without
- // names.
- var name = nextValue.name ? nextValue.name : '<arg #' + j + '>';
- map[name] = devtools.DebuggerAgent.formatObjectReference_(nextValue.value);
+ map[name] = true;
+ var value = devtools.DebuggerAgent.formatObjectProxy_(property.value);
+ var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value);
+ result.push(propertyProxy);
}
};
@@ -817,26 +1057,32 @@ devtools.DebuggerAgent.argumentsArrayToMap_ = function(array, map) {
* @param {Object} v An object reference from the debugger response.
* @return {*} The value representation expected by ScriptsPanel.
*/
-devtools.DebuggerAgent.formatObjectReference_ = function(v) {
+devtools.DebuggerAgent.formatObjectProxy_ = function(v) {
+ var description;
+ var hasChildren = false;
if (v.type == 'object') {
- return v;
+ description = v.className;
+ hasChildren = true;
} else if (v.type == 'function') {
- var f = function() {};
- f.ref = v.ref;
- return f;
+ if (v.source) {
+ description = v.source;
+ } else {
+ description = 'function ' + v.name + '()';
+ }
+ hasChildren = true;
} else if (goog.isDef(v.value)) {
- return v.value;
+ description = v.value;
} else if (v.type == 'undefined') {
- return 'undefined';
+ description = 'undefined';
} else if (v.type == 'null') {
- return 'null';
- } else if (v.name) {
- return v.name;
- } else if (v.className) {
- return v.className;
+ description = 'null';
} else {
- return '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>';
+ description = '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>';
}
+ var proxy = new WebInspector.ObjectProxy(v, [], 0, description, hasChildren);
+ proxy.type = v.type;
+ proxy.isV8Ref = true;
+ return proxy;
};
@@ -862,13 +1108,22 @@ devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) {
/**
* @param {number} scriptId Id of the script.
+ * @param {?string} url Script resource URL if any.
* @param {number} lineOffset First line 0-based offset in the containing
* document.
+ * @param {string} contextType Type of the script's context:
+ * "page" - regular script from html page
+ * "injected" - extension content script
+ * @param {bool} opt_isUnresolved If true, script will not be resolved.
* @constructor
*/
-devtools.ScriptInfo = function(scriptId, lineOffset) {
+devtools.ScriptInfo = function(
+ scriptId, url, lineOffset, contextType, opt_isUnresolved) {
this.scriptId_ = scriptId;
this.lineOffset_ = lineOffset;
+ this.contextType_ = contextType;
+ this.url_ = url;
+ this.isUnresolved_ = opt_isUnresolved;
this.lineToBreakpointInfo_ = {};
};
@@ -883,6 +1138,30 @@ devtools.ScriptInfo.prototype.getLineOffset = function() {
/**
+ * @return {string}
+ */
+devtools.ScriptInfo.prototype.getContextType = function() {
+ return this.contextType_;
+};
+
+
+/**
+ * @return {?string}
+ */
+devtools.ScriptInfo.prototype.getUrl = function() {
+ return this.url_;
+};
+
+
+/**
+ * @return {?bool}
+ */
+devtools.ScriptInfo.prototype.isUnresolved = function() {
+ return this.isUnresolved_;
+};
+
+
+/**
* @param {number} line 0-based line number in the script.
* @return {?devtools.BreakpointInfo} Information on a breakpoint at the
* specified line in the script or undefined if there is no breakpoint at
@@ -913,12 +1192,10 @@ devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) {
/**
- * @param {number} scriptId Id of the owning script.
* @param {number} line Breakpoint 0-based line number in the containing script.
* @constructor
*/
-devtools.BreakpointInfo = function(sourceId, line) {
- this.sourceId_ = sourceId;
+devtools.BreakpointInfo = function(line) {
this.line_ = line;
this.v8id_ = -1;
this.removed_ = false;
@@ -928,14 +1205,6 @@ devtools.BreakpointInfo = function(sourceId, line) {
/**
* @return {number}
*/
-devtools.BreakpointInfo.prototype.getSourceId = function(n) {
- return this.sourceId_;
-};
-
-
-/**
- * @return {number}
- */
devtools.BreakpointInfo.prototype.getLine = function(n) {
return this.line_;
};
@@ -977,50 +1246,51 @@ devtools.BreakpointInfo.prototype.isRemoved = function() {
/**
* Call stack frame data.
+ * @param {string} id CallFrame id.
+ * @param {string} type CallFrame type.
+ * @param {string} functionName CallFrame type.
+ * @param {string} sourceID Source id.
+ * @param {number} line Source line.
+ * @param {Array.<Object>} scopeChain Array of scoped objects.
* @construnctor
*/
-devtools.CallFrame = function() {
- this.sourceID = null;
- this.line = null;
- this.type = 'function';
- this.functionName = null;
- this.caller = null;
- this.localScope = null;
- this.scopeChain = [];
- this.thisObject = {};
- this.frameNumber = null;
+devtools.CallFrame = function(id, type, functionName, sourceID, line,
+ scopeChain) {
+ this.id = id;
+ this.type = type;
+ this.functionName = functionName;
+ this.sourceID = sourceID;
+ this.line = line;
+ this.scopeChain = scopeChain;
};
/**
- * This method is called by
- * WebInspector.ScriptsPanel.evaluateInSelectedCallFrame. This method issues
- * asynchronous evaluate request.
+ * This method issues asynchronous evaluate request, reports result to the
+ * callback.
* @param {string} expression An expression to be evaluated in the context of
* this call frame.
- * @return {string} User message that the expression is being evaluated.
+ * @param {function(Object):undefined} callback Callback to report result to.
*/
-devtools.CallFrame.prototype.evaluate = function(expression) {
+devtools.CallFrame.prototype.evaluate_ = function(expression, callback) {
devtools.tools.getDebuggerAgent().requestEvaluate({
- 'expression': expression,
- 'frame': this.frameNumber,
- 'global': false,
- 'disable_break': false
- },
- devtools.CallFrame.handleEvaluateResponse_);
- return 'evaluating...';
-};
-
-
-/**
- * Handles 'evaluate' response for a call frame
- * @param {devtools.DebuggerMessage} response
- */
-devtools.CallFrame.handleEvaluateResponse_ = function(response) {
- var body = response.getBody();
- var value = devtools.DebuggerAgent.formatObjectReference_(body);
- WebInspector.addMessageToConsole(new WebInspector.ConsoleCommandResult(
- value, false /* exception */, null /* commandMessage */));
+ 'expression': expression,
+ 'frame': this.id,
+ 'global': false,
+ 'disable_break': false,
+ 'compactFormat': true
+ },
+ function(response) {
+ var result = {};
+ if (response.isSuccess()) {
+ result.value = devtools.DebuggerAgent.formatObjectProxy_(
+ response.getBody());
+ } else {
+ result.value = response.getMessage();
+ result.isException = true;
+ }
+ callback(result);
+ });
};
@@ -1078,8 +1348,7 @@ devtools.DebugCommand.prototype.toJSONProtocol = function() {
* @constructor
*/
devtools.DebuggerMessage = function(msg) {
- var jsExpression = '[' + msg + '][0]';
- this.packet_ = eval(jsExpression);
+ this.packet_ = JSON.parse(msg);
this.refs_ = [];
if (this.packet_.refs) {
for (var i = 0; i < this.packet_.refs.length; i++) {

Powered by Google App Engine
This is Rietveld 408576698