diff options
-rw-r--r-- | chrome/renderer/devtools_agent.cc | 68 | ||||
-rw-r--r-- | chrome/renderer/devtools_agent.h | 11 | ||||
-rw-r--r-- | chrome/renderer/devtools_client.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/devtools_client.h | 1 | ||||
-rw-r--r-- | chrome/renderer/devtools_messages_internal.h | 22 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_impl.cc | 2 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_manager.cc | 8 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_manager.h | 4 | ||||
-rw-r--r-- | webkit/glue/devtools/js/debugger_agent.js | 116 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inspector_controller_impl.js | 13 |
10 files changed, 139 insertions, 112 deletions
diff --git a/chrome/renderer/devtools_agent.cc b/chrome/renderer/devtools_agent.cc index d08b0c7..7497cc6 100644 --- a/chrome/renderer/devtools_agent.cc +++ b/chrome/renderer/devtools_agent.cc @@ -29,8 +29,7 @@ DevToolsAgent::DevToolsAgent(int routing_id, RenderView* view, MessageLoop* view_loop) - : debugger_(NULL), - routing_id_(routing_id), + : routing_id_(routing_id), view_(view), view_loop_(view_loop), channel_(NULL), @@ -84,10 +83,6 @@ bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message) IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach, OnAttach) IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach, OnDetach) - IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugAttach, OnDebugAttach) - IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugDetach, OnDebugDetach) - IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugBreak, OnDebugBreak) - IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugCommand, OnDebugCommand) IPC_MESSAGE_HANDLER(DevToolsAgentMsg_RpcMessage, OnRpcMessage) IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebuggerCommand, OnDebuggerCommand) @@ -103,10 +98,6 @@ void DevToolsAgent::OnFilterRemoved() { channel_ = NULL; } -void DevToolsAgent::DebuggerOutput(const std::wstring& out) { - Send(DevToolsClientMsg_DebuggerOutput(out)); -} - void DevToolsAgent::EvaluateScript(const std::wstring& script) { DCHECK(MessageLoop::current() == view_loop_); // view_ may have been cleared after this method execution was scheduled. @@ -124,63 +115,6 @@ void DevToolsAgent::OnDetach() { this, &DevToolsAgent::Detach)); } -void DevToolsAgent::OnDebugAttach() { - DCHECK(MessageLoop::current() == io_loop_); - if (!debugger_) { - debugger_ = new DebuggerBridge(this); - } - - debugger_->Attach(); - - Send(DevToolsClientMsg_DidDebugAttach()); - - // TODO(yurys): remove this macros once plugins available on other platforms -#if defined(OS_WIN) - // Tell the plugin host to stop accepting messages in order to avoid - // hangs while the renderer is paused. - // TODO(yurys): It might be an improvement to add more plumbing to do this - // when the renderer is actually paused vs. just the debugger being attached. - // http://code.google.com/p/chromium/issues/detail?id=7556 - PluginChannelHost::SetListening(false); -#endif // OS_WIN -} - -void DevToolsAgent::OnDebugDetach() { - DCHECK(MessageLoop::current() == io_loop_); - if (debugger_) - debugger_->Detach(); - // TODO(yurys): remove this macros once plugins available on other platforms -#if defined(OS_WIN) - PluginChannelHost::SetListening(true); -#endif // OS_WIN -} - -void DevToolsAgent::OnDebugBreak(bool force) { - DCHECK(MessageLoop::current() == io_loop_); - // Set the debug break flag in the V8 engine. - debugger_->Break(force); - - // If a forced break has been requested make sure that it will occour by - // running some JavaScript in the renderer. - if (force && view_loop_) { - view_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &DevToolsAgent::EvaluateScript, - std::wstring(L"javascript:void(0)"))); - } -} - -void DevToolsAgent::OnDebugCommand(const std::wstring& cmd) { - DCHECK(MessageLoop::current() == io_loop_); - if (!debugger_) { - NOTREACHED(); - std::wstring msg = - StringPrintf(L"before attach, ignored command (%S)", cmd.c_str()); - DebuggerOutput(msg); - } else { - debugger_->Command(cmd); - } -} - void DevToolsAgent::SendMessageToClient(const std::string& raw_msg) { Send(DevToolsClientMsg_RpcMessage(raw_msg)); } diff --git a/chrome/renderer/devtools_agent.h b/chrome/renderer/devtools_agent.h index c5866e5..24bba31 100644 --- a/chrome/renderer/devtools_agent.h +++ b/chrome/renderer/devtools_agent.h @@ -12,7 +12,6 @@ #include "base/scoped_ptr.h" #include "chrome/common/ipc_channel_proxy.h" #include "chrome/renderer/devtools_messages.h" -#include "webkit/glue/debugger_bridge.h" #include "webkit/glue/webdevtoolsagent_delegate.h" class MessageLoop; @@ -24,7 +23,6 @@ class WebDevToolsAgent; // go through browser process. On the renderer side of the tools UI there's // a corresponding ToolsClient object. class DevToolsAgent : public IPC::ChannelProxy::MessageFilter, - public DebuggerBridge::Delegate, public WebDevToolsAgentDelegate { public: // DevToolsAgent is a field of the RenderView. The view is supposed to remove @@ -52,9 +50,6 @@ class DevToolsAgent : public IPC::ChannelProxy::MessageFilter, virtual bool OnMessageReceived(const IPC::Message& message); virtual void OnFilterRemoved(); - // Debugger::Delegate callback method to handle debugger output. - void DebuggerOutput(const std::wstring& out); - void Attach(); void Detach(); void DispatchRpcMessage(const std::string& raw_msg); @@ -68,16 +63,10 @@ class DevToolsAgent : public IPC::ChannelProxy::MessageFilter, // handle debug messages even when v8 is stopped. void OnAttach(); void OnDetach(); - void OnDebugAttach(); - void OnDebugDetach(); - void OnDebugBreak(bool force); - void OnDebugCommand(const std::wstring& cmd); void OnRpcMessage(const std::string& raw_msg); void OnDebuggerCommand(const std::string& command); void OnInspectElement(int x, int y); - scoped_refptr<DebuggerBridge> debugger_; - int routing_id_; // View routing id that we can access from IO thread. RenderView* view_; MessageLoop* view_loop_; diff --git a/chrome/renderer/devtools_client.cc b/chrome/renderer/devtools_client.cc index 240fda3..a8a9fbb 100644 --- a/chrome/renderer/devtools_client.cc +++ b/chrome/renderer/devtools_client.cc @@ -30,7 +30,6 @@ bool DevToolsClient::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(DevToolsClient, message) - IPC_MESSAGE_HANDLER(DevToolsClientMsg_DidDebugAttach, DidDebugAttach) IPC_MESSAGE_HANDLER(DevToolsClientMsg_RpcMessage, OnRpcMessage) IPC_MESSAGE_UNHANDLED(handled = false); IPC_END_MESSAGE_MAP() @@ -38,11 +37,6 @@ bool DevToolsClient::OnMessageReceived(const IPC::Message& message) { return handled; } -void DevToolsClient::DidDebugAttach() { - DCHECK(RenderThread::current()->message_loop() == MessageLoop::current()); - // TODO(yurys): delegate to JS frontend. -} - void DevToolsClient::SendMessageToAgent(const std::string& raw_msg) { Send(DevToolsAgentMsg_RpcMessage(raw_msg)); } diff --git a/chrome/renderer/devtools_client.h b/chrome/renderer/devtools_client.h index 6e85845..2a6bb9e 100644 --- a/chrome/renderer/devtools_client.h +++ b/chrome/renderer/devtools_client.h @@ -38,7 +38,6 @@ class DevToolsClient : public WebDevToolsClientDelegate { virtual void SendDebuggerCommandToAgent(const std::string& command); private: - void DidDebugAttach(); void OnRpcMessage(const std::string& raw_msg); // Sends message to DevToolsAgent. diff --git a/chrome/renderer/devtools_messages_internal.h b/chrome/renderer/devtools_messages_internal.h index fe4ffde..b0e0a8a 100644 --- a/chrome/renderer/devtools_messages_internal.h +++ b/chrome/renderer/devtools_messages_internal.h @@ -48,14 +48,6 @@ // browser. IPC_BEGIN_MESSAGES(DevToolsClient) - // Response message for DevToolsAgentMsg_DebugAttach. - IPC_MESSAGE_CONTROL0(DevToolsClientMsg_DidDebugAttach) - - // WebKit and JavaScript error messages to log to the console - // or debugger UI. - IPC_MESSAGE_CONTROL1(DevToolsClientMsg_DebuggerOutput, - std::wstring /* msg */) - // Sends glue-level Rpc message to the client. IPC_MESSAGE_CONTROL1(DevToolsClientMsg_RpcMessage, std::string /* raw_msg */) @@ -74,20 +66,6 @@ IPC_BEGIN_MESSAGES(DevToolsAgent) // Tells agent that there is no longer a client host connected to it. IPC_MESSAGE_CONTROL0(DevToolsAgentMsg_Detach) - // Initialize the V8 debugger in the renderer. - IPC_MESSAGE_CONTROL0(DevToolsAgentMsg_DebugAttach) - - // Shutdown the V8 debugger in the renderer. - IPC_MESSAGE_CONTROL0(DevToolsAgentMsg_DebugDetach) - - // Break V8 execution. - IPC_MESSAGE_CONTROL1(DevToolsAgentMsg_DebugBreak, - bool /* force */) - - // Send a command to the V8 debugger. - IPC_MESSAGE_CONTROL1(DevToolsAgentMsg_DebugCommand, - std::wstring /* cmd */) - // Sends glue-level Rpc message to the agent. IPC_MESSAGE_CONTROL1(DevToolsAgentMsg_RpcMessage, std::string /* raw_msg */) diff --git a/webkit/glue/devtools/debugger_agent_impl.cc b/webkit/glue/devtools/debugger_agent_impl.cc index b52db2a..4edd3db 100644 --- a/webkit/glue/devtools/debugger_agent_impl.cc +++ b/webkit/glue/devtools/debugger_agent_impl.cc @@ -33,7 +33,7 @@ DebuggerAgentImpl::~DebuggerAgentImpl() { } void DebuggerAgentImpl::DebugBreak() { - // TODO(yurys): implement + DebuggerAgentManager::DebugBreak(this); } void DebuggerAgentImpl::DebuggerOutput(const std::string& command) { diff --git a/webkit/glue/devtools/debugger_agent_manager.cc b/webkit/glue/devtools/debugger_agent_manager.cc index d6ab21c..3af22e6 100644 --- a/webkit/glue/devtools/debugger_agent_manager.cc +++ b/webkit/glue/devtools/debugger_agent_manager.cc @@ -59,6 +59,14 @@ void DebuggerAgentManager::DebugDetach(DebuggerAgentImpl* debugger_agent) { } // static +void DebuggerAgentManager::DebugBreak(DebuggerAgentImpl* debugger_agent) { +#if USE(V8) + DCHECK(attached_agents_->contains(debugger_agent)); + v8::Debug::DebugBreak(); +#endif +} + +// static void DebuggerAgentManager::DebuggerOutput(const std::string& out) { DebuggerAgentImpl* agent = GetAgentForCurrentV8Context(); if (!agent) { diff --git a/webkit/glue/devtools/debugger_agent_manager.h b/webkit/glue/devtools/debugger_agent_manager.h index 380bb0d..ba48966 100644 --- a/webkit/glue/devtools/debugger_agent_manager.h +++ b/webkit/glue/devtools/debugger_agent_manager.h @@ -24,10 +24,14 @@ class DebuggerAgentImpl; // would expect some actions from the handler. If there is no appropriate // debugger agent to handle such messages the manager should perform the action // itself, otherwise v8 may hang waiting for the action. +// +// TODO(yurys): disable plugin message handling while v8 is paused on a +// breakpoint. class DebuggerAgentManager { public: static void DebugAttach(DebuggerAgentImpl* debugger_agent); static void DebugDetach(DebuggerAgentImpl* debugger_agent); + static void DebugBreak(DebuggerAgentImpl* debugger_agent); static void DebugCommand(const std::string& command); static void ExecuteDebuggerCommand(const std::string& command); diff --git a/webkit/glue/devtools/js/debugger_agent.js b/webkit/glue/devtools/js/debugger_agent.js index b22ff20..401c998 100644 --- a/webkit/glue/devtools/js/debugger_agent.js +++ b/webkit/glue/devtools/js/debugger_agent.js @@ -55,6 +55,14 @@ devtools.DebuggerAgent.prototype.requestScripts = function() { /** + * Tells the v8 debugger to stop on as soon as possible. + */ +devtools.DebuggerAgent.prototype.pauseExecution = function() { + RemoteDebuggerAgent.DebugBreak(); +}; + + +/** * @param {number} sourceId Id of the script fot the breakpoint. * @param {number} line Number of the line for the breakpoint. */ @@ -86,6 +94,31 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) { /** + * @param {number} sourceId Id of the script fot the breakpoint. + * @param {number} line Number of the line for the breakpoint. + */ +devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) { + var script = this.parsedScripts_[sourceId]; + if (!script) { + return; + } + + var breakpointInfo = script.getBreakpointInfo(line); + script.removeBreakpointInfo(breakpointInfo); + breakpointInfo.markAsRemoved(); + + var id = breakpointInfo.getV8Id(); + + // If we don't know id of this breakpoint in the v8 debugger we cannot send + // 'clearbreakpoint' request. In that case it will be removed in + // 'setbreakpoint' response handler when we learn the id. + if (id != -1) { + this.requestClearBreakpoint_(id); + } +}; + + +/** * Tells the v8 debugger to step into the next statement. */ devtools.DebuggerAgent.prototype.stepIntoStatement = function() { @@ -113,7 +146,7 @@ devtools.DebuggerAgent.prototype.stepOverStatement = function() { * Tells the v8 debugger to continue execution after it has been stopped on a * breakpoint or an exception. */ -devtools.DebuggerAgent.prototype.continueExecution = function() { +devtools.DebuggerAgent.prototype.resumeExecution = function() { var cmd = new devtools.DebugCommand('continue'); devtools.DebuggerAgent.sendCommand_(cmd); }; @@ -129,6 +162,19 @@ devtools.DebuggerAgent.prototype.getCurrentCallFrame = function() { /** + * Removes specified breakpoint from the v8 debugger. + * @param {number} breakpointId Id of the breakpoint in the v8 debugger. + */ +devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function( + breakpointId) { + var cmd = new devtools.DebugCommand('clearbreakpoint', { + 'breakpoint': breakpointId + }); + devtools.DebuggerAgent.sendCommand_(cmd); +}; + + +/** * Sends 'backtrace' request to v8. */ devtools.DebuggerAgent.prototype.requestBacktrace_ = function() { @@ -183,6 +229,8 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) { this.handleScriptsResponse_(msg); } else if (msg.getCommand() == 'setbreakpoint') { this.handleSetBreakpointResponse_(msg); + } else if (msg.getCommand() == 'clearbreakpoint') { + this.handleClearBreakpointResponse_(msg); } else if (msg.getCommand() == 'backtrace') { this.handleBacktraceResponse_(msg); } @@ -199,7 +247,9 @@ devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) { this.currentCallFrame_ = { 'sourceID': body.script.id, 'line': body.sourceLine - body.script.lineOffset +1, - 'script': body.script + 'script': body.script, + 'scopeChain': [], + 'thisObject': {} }; this.requestBacktrace_(); @@ -240,6 +290,19 @@ devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) { } var idInV8 = msg.getBody().breakpoint; breakpointInfo.setV8Id(idInV8); + + if (breakpointInfo.isRemoved()) { + this.requestClearBreakpoint_(idInV8); + } +}; + + +/** + * @param {devtools.DebuggerMessage} msg + */ +devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function( + msg) { + // Do nothing. }; @@ -285,7 +348,9 @@ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { 'line': nextFrame.line - script.lineOffset +1, 'type': 'function', 'functionName': funcName, //nextFrame.text, - 'caller': caller + 'caller': caller, + 'scopeChain': [], + 'thisObject': {} }; caller = f; } @@ -304,7 +369,7 @@ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { */ devtools.ScriptInfo = function(scriptId, lineOffset) { this.scriptId_ = scriptId; - this.lineOffset_ = lineOffset; + this.lineOffset_ = lineOffset; this.lineToBreakpointInfo_ = {}; }; @@ -338,6 +403,15 @@ devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint) { }; +/** + * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed. + */ +devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) { + var line = breakpoint.getLine(); + delete this.lineToBreakpointInfo_[line]; +}; + + /** * @param {number} scriptId Id of the owning script. @@ -348,6 +422,15 @@ devtools.BreakpointInfo = function(sourceId, line) { this.sourceId_ = sourceId; this.line_ = line; this.v8id_ = -1; + this.removed_ = false; +}; + + +/** + * @return {number} + */ +devtools.BreakpointInfo.prototype.getSourceId = function(n) { + return this.sourceId_; }; @@ -360,6 +443,14 @@ devtools.BreakpointInfo.prototype.getLine = function(n) { /** + * @return {number} Unique identifier of this breakpoint in the v8 debugger. + */ +devtools.BreakpointInfo.prototype.getV8Id = function(n) { + return this.v8id_; +}; + + +/** * Sets id of this breakpoint in the v8 debugger. * @param {number} id */ @@ -368,6 +459,23 @@ devtools.BreakpointInfo.prototype.setV8Id = function(id) { }; +/** + * Marks this breakpoint as removed from the front-end. + */ +devtools.BreakpointInfo.prototype.markAsRemoved = function() { + this.removed_ = true; +}; + + +/** + * @return {boolean} Whether this breakpoint has been removed from the + * front-end. + */ +devtools.BreakpointInfo.prototype.isRemoved = function() { + return this.removed_; +}; + + /** * JSON based commands sent to v8 debugger. diff --git a/webkit/glue/devtools/js/inspector_controller_impl.js b/webkit/glue/devtools/js/inspector_controller_impl.js index 955b8ff..2ce61f5 100644 --- a/webkit/glue/devtools/js/inspector_controller_impl.js +++ b/webkit/glue/devtools/js/inspector_controller_impl.js @@ -22,6 +22,12 @@ devtools.InspectorControllerImpl = function() { }, get Element() { return devtools.DomNode; + }, + /** + * See usages in ScopeChainSidebarPane.js where it's called as + * constructor. + */ + Object : function() { } }; }; @@ -109,10 +115,17 @@ devtools.InspectorControllerImpl.prototype.addBreakpoint = function( devtools.InspectorControllerImpl.prototype.removeBreakpoint = function( sourceID, line) { + devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line); +}; + + +devtools.InspectorController.prototype.pauseInDebugger = function() { + devtools.tools.getDebuggerAgent().pauseExecution(); }; devtools.InspectorControllerImpl.prototype.resumeDebugger = function() { + devtools.tools.getDebuggerAgent().resumeExecution(); }; |