LCOV - code coverage report
Current view: top level - src/inspector - v8-inspector-session-impl.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 132 205 64.4 %
Date: 2017-10-20 Functions: 29 42 69.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/inspector/v8-inspector-session-impl.h"
       6             : 
       7             : #include "src/inspector/injected-script.h"
       8             : #include "src/inspector/inspected-context.h"
       9             : #include "src/inspector/protocol/Protocol.h"
      10             : #include "src/inspector/remote-object-id.h"
      11             : #include "src/inspector/search-util.h"
      12             : #include "src/inspector/string-util.h"
      13             : #include "src/inspector/v8-console-agent-impl.h"
      14             : #include "src/inspector/v8-debugger-agent-impl.h"
      15             : #include "src/inspector/v8-debugger.h"
      16             : #include "src/inspector/v8-heap-profiler-agent-impl.h"
      17             : #include "src/inspector/v8-inspector-impl.h"
      18             : #include "src/inspector/v8-profiler-agent-impl.h"
      19             : #include "src/inspector/v8-runtime-agent-impl.h"
      20             : #include "src/inspector/v8-schema-agent-impl.h"
      21             : 
      22             : namespace v8_inspector {
      23             : 
      24             : // static
      25           0 : bool V8InspectorSession::canDispatchMethod(const StringView& method) {
      26             :   return stringViewStartsWith(method,
      27           0 :                               protocol::Runtime::Metainfo::commandPrefix) ||
      28             :          stringViewStartsWith(method,
      29           0 :                               protocol::Debugger::Metainfo::commandPrefix) ||
      30             :          stringViewStartsWith(method,
      31           0 :                               protocol::Profiler::Metainfo::commandPrefix) ||
      32             :          stringViewStartsWith(
      33           0 :              method, protocol::HeapProfiler::Metainfo::commandPrefix) ||
      34             :          stringViewStartsWith(method,
      35           0 :                               protocol::Console::Metainfo::commandPrefix) ||
      36             :          stringViewStartsWith(method,
      37           0 :                               protocol::Schema::Metainfo::commandPrefix);
      38             : }
      39             : 
      40             : // static
      41           0 : int V8ContextInfo::executionContextId(v8::Local<v8::Context> context) {
      42           0 :   return InspectedContext::contextId(context);
      43             : }
      44             : 
      45        3406 : std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(
      46             :     V8InspectorImpl* inspector, int contextGroupId, int sessionId,
      47             :     V8Inspector::Channel* channel, const StringView& state) {
      48             :   return std::unique_ptr<V8InspectorSessionImpl>(new V8InspectorSessionImpl(
      49        6812 :       inspector, contextGroupId, sessionId, channel, state));
      50             : }
      51             : 
      52        3406 : V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
      53             :                                                int contextGroupId,
      54             :                                                int sessionId,
      55             :                                                V8Inspector::Channel* channel,
      56        6812 :                                                const StringView& savedState)
      57             :     : m_contextGroupId(contextGroupId),
      58             :       m_sessionId(sessionId),
      59             :       m_inspector(inspector),
      60             :       m_channel(channel),
      61             :       m_customObjectFormatterEnabled(false),
      62             :       m_dispatcher(this),
      63             :       m_state(nullptr),
      64             :       m_runtimeAgent(nullptr),
      65             :       m_debuggerAgent(nullptr),
      66             :       m_heapProfilerAgent(nullptr),
      67             :       m_profilerAgent(nullptr),
      68             :       m_consoleAgent(nullptr),
      69        3406 :       m_schemaAgent(nullptr) {
      70        3406 :   if (savedState.length()) {
      71             :     std::unique_ptr<protocol::Value> state =
      72          80 :         protocol::StringUtil::parseJSON(toString16(savedState));
      73          40 :     if (state) m_state = protocol::DictionaryValue::cast(std::move(state));
      74          40 :     if (!m_state) m_state = protocol::DictionaryValue::create();
      75             :   } else {
      76        6732 :     m_state = protocol::DictionaryValue::create();
      77             :   }
      78             : 
      79             :   m_runtimeAgent.reset(new V8RuntimeAgentImpl(
      80        6812 :       this, this, agentState(protocol::Runtime::Metainfo::domainName)));
      81        3406 :   protocol::Runtime::Dispatcher::wire(&m_dispatcher, m_runtimeAgent.get());
      82             : 
      83             :   m_debuggerAgent.reset(new V8DebuggerAgentImpl(
      84        6812 :       this, this, agentState(protocol::Debugger::Metainfo::domainName)));
      85        3406 :   protocol::Debugger::Dispatcher::wire(&m_dispatcher, m_debuggerAgent.get());
      86             : 
      87             :   m_profilerAgent.reset(new V8ProfilerAgentImpl(
      88        6812 :       this, this, agentState(protocol::Profiler::Metainfo::domainName)));
      89        3406 :   protocol::Profiler::Dispatcher::wire(&m_dispatcher, m_profilerAgent.get());
      90             : 
      91             :   m_heapProfilerAgent.reset(new V8HeapProfilerAgentImpl(
      92        6812 :       this, this, agentState(protocol::HeapProfiler::Metainfo::domainName)));
      93             :   protocol::HeapProfiler::Dispatcher::wire(&m_dispatcher,
      94        3406 :                                            m_heapProfilerAgent.get());
      95             : 
      96             :   m_consoleAgent.reset(new V8ConsoleAgentImpl(
      97        6812 :       this, this, agentState(protocol::Console::Metainfo::domainName)));
      98        3406 :   protocol::Console::Dispatcher::wire(&m_dispatcher, m_consoleAgent.get());
      99             : 
     100             :   m_schemaAgent.reset(new V8SchemaAgentImpl(
     101        6812 :       this, this, agentState(protocol::Schema::Metainfo::domainName)));
     102        3406 :   protocol::Schema::Dispatcher::wire(&m_dispatcher, m_schemaAgent.get());
     103             : 
     104        3406 :   if (savedState.length()) {
     105          40 :     m_runtimeAgent->restore();
     106          40 :     m_debuggerAgent->restore();
     107          40 :     m_heapProfilerAgent->restore();
     108          40 :     m_profilerAgent->restore();
     109          40 :     m_consoleAgent->restore();
     110             :   }
     111        3406 : }
     112             : 
     113       13624 : V8InspectorSessionImpl::~V8InspectorSessionImpl() {
     114        3406 :   discardInjectedScripts();
     115        6812 :   m_consoleAgent->disable();
     116        6812 :   m_profilerAgent->disable();
     117        6812 :   m_heapProfilerAgent->disable();
     118        6812 :   m_debuggerAgent->disable();
     119        6812 :   m_runtimeAgent->disable();
     120        3406 :   m_inspector->disconnect(this);
     121        6812 : }
     122             : 
     123       20436 : protocol::DictionaryValue* V8InspectorSessionImpl::agentState(
     124             :     const String16& name) {
     125       20436 :   protocol::DictionaryValue* state = m_state->getObject(name);
     126       20436 :   if (!state) {
     127             :     std::unique_ptr<protocol::DictionaryValue> newState =
     128       20196 :         protocol::DictionaryValue::create();
     129             :     state = newState.get();
     130       40392 :     m_state->setObject(name, std::move(newState));
     131             :   }
     132       20436 :   return state;
     133             : }
     134             : 
     135             : namespace {
     136             : 
     137      820590 : class MessageBuffer : public StringBuffer {
     138             :  public:
     139      273530 :   static std::unique_ptr<MessageBuffer> create(
     140             :       std::unique_ptr<protocol::Serializable> message) {
     141             :     return std::unique_ptr<MessageBuffer>(
     142      273530 :         new MessageBuffer(std::move(message)));
     143             :   }
     144             : 
     145      273530 :   const StringView& string() override {
     146      273530 :     if (!m_serialized) {
     147      820590 :       m_serialized = StringBuffer::create(toStringView(m_message->serialize()));
     148             :       m_message.reset(nullptr);
     149             :     }
     150      273530 :     return m_serialized->string();
     151             :   }
     152             : 
     153             :  private:
     154             :   explicit MessageBuffer(std::unique_ptr<protocol::Serializable> message)
     155      547060 :       : m_message(std::move(message)) {}
     156             : 
     157             :   std::unique_ptr<protocol::Serializable> m_message;
     158             :   std::unique_ptr<StringBuffer> m_serialized;
     159             : };
     160             : 
     161             : }  // namespace
     162             : 
     163      140343 : void V8InspectorSessionImpl::sendProtocolResponse(
     164             :     int callId, std::unique_ptr<protocol::Serializable> message) {
     165      842058 :   m_channel->sendResponse(callId, MessageBuffer::create(std::move(message)));
     166      140343 : }
     167             : 
     168      133187 : void V8InspectorSessionImpl::sendProtocolNotification(
     169             :     std::unique_ptr<protocol::Serializable> message) {
     170      799122 :   m_channel->sendNotification(MessageBuffer::create(std::move(message)));
     171      133187 : }
     172             : 
     173        6875 : void V8InspectorSessionImpl::flushProtocolNotifications() {
     174        6875 :   m_channel->flushProtocolNotifications();
     175        6875 : }
     176             : 
     177           0 : void V8InspectorSessionImpl::reset() {
     178           0 :   m_debuggerAgent->reset();
     179           0 :   m_runtimeAgent->reset();
     180           0 :   discardInjectedScripts();
     181           0 : }
     182             : 
     183        3406 : void V8InspectorSessionImpl::discardInjectedScripts() {
     184             :   m_inspectedObjects.clear();
     185        3406 :   int sessionId = m_sessionId;
     186             :   m_inspector->forEachContext(m_contextGroupId,
     187             :                               [&sessionId](InspectedContext* context) {
     188        3396 :                                 context->discardInjectedScript(sessionId);
     189        6812 :                               });
     190        3406 : }
     191             : 
     192      233478 : Response V8InspectorSessionImpl::findInjectedScript(
     193             :     int contextId, InjectedScript*& injectedScript) {
     194      233478 :   injectedScript = nullptr;
     195             :   InspectedContext* context =
     196      233478 :       m_inspector->getContext(m_contextGroupId, contextId);
     197      233503 :   if (!context) return Response::Error("Cannot find context with specified id");
     198      233453 :   injectedScript = context->getInjectedScript(m_sessionId);
     199      233453 :   if (!injectedScript) {
     200        2944 :     if (!context->createInjectedScript(m_sessionId))
     201           0 :       return Response::Error("Cannot access specified execution context");
     202        2944 :     injectedScript = context->getInjectedScript(m_sessionId);
     203        2944 :     if (m_customObjectFormatterEnabled)
     204           5 :       injectedScript->setCustomObjectFormatterEnabled(true);
     205             :   }
     206      233453 :   return Response::OK();
     207             : }
     208             : 
     209       88077 : Response V8InspectorSessionImpl::findInjectedScript(
     210             :     RemoteObjectIdBase* objectId, InjectedScript*& injectedScript) {
     211       88077 :   return findInjectedScript(objectId->contextId(), injectedScript);
     212             : }
     213             : 
     214           0 : void V8InspectorSessionImpl::releaseObjectGroup(const StringView& objectGroup) {
     215           0 :   releaseObjectGroup(toString16(objectGroup));
     216           0 : }
     217             : 
     218       41296 : void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) {
     219       41296 :   int sessionId = m_sessionId;
     220             :   m_inspector->forEachContext(
     221       41296 :       m_contextGroupId, [&objectGroup, &sessionId](InspectedContext* context) {
     222       41296 :         InjectedScript* injectedScript = context->getInjectedScript(sessionId);
     223       41296 :         if (injectedScript) injectedScript->releaseObjectGroup(objectGroup);
     224      123888 :       });
     225       41296 : }
     226             : 
     227           0 : bool V8InspectorSessionImpl::unwrapObject(
     228             :     std::unique_ptr<StringBuffer>* error, const StringView& objectId,
     229             :     v8::Local<v8::Value>* object, v8::Local<v8::Context>* context,
     230             :     std::unique_ptr<StringBuffer>* objectGroup) {
     231           0 :   String16 objectGroupString;
     232             :   Response response = unwrapObject(toString16(objectId), object, context,
     233           0 :                                    objectGroup ? &objectGroupString : nullptr);
     234           0 :   if (!response.isSuccess()) {
     235           0 :     if (error) {
     236           0 :       String16 errorMessage = response.errorMessage();
     237           0 :       *error = StringBufferImpl::adopt(errorMessage);
     238             :     }
     239             :     return false;
     240             :   }
     241           0 :   if (objectGroup) *objectGroup = StringBufferImpl::adopt(objectGroupString);
     242             :   return true;
     243             : }
     244             : 
     245           0 : Response V8InspectorSessionImpl::unwrapObject(const String16& objectId,
     246             :                                               v8::Local<v8::Value>* object,
     247             :                                               v8::Local<v8::Context>* context,
     248             :                                               String16* objectGroup) {
     249           0 :   std::unique_ptr<RemoteObjectId> remoteId;
     250           0 :   Response response = RemoteObjectId::parse(objectId, &remoteId);
     251           0 :   if (!response.isSuccess()) return response;
     252           0 :   InjectedScript* injectedScript = nullptr;
     253           0 :   response = findInjectedScript(remoteId.get(), injectedScript);
     254           0 :   if (!response.isSuccess()) return response;
     255           0 :   response = injectedScript->findObject(*remoteId, object);
     256           0 :   if (!response.isSuccess()) return response;
     257           0 :   *context = injectedScript->context()->context();
     258           0 :   if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId);
     259           0 :   return Response::OK();
     260             : }
     261             : 
     262             : std::unique_ptr<protocol::Runtime::API::RemoteObject>
     263           0 : V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context,
     264             :                                    v8::Local<v8::Value> value,
     265             :                                    const StringView& groupName) {
     266           0 :   return wrapObject(context, value, toString16(groupName), false);
     267             : }
     268             : 
     269             : std::unique_ptr<protocol::Runtime::RemoteObject>
     270        6455 : V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context,
     271             :                                    v8::Local<v8::Value> value,
     272             :                                    const String16& groupName,
     273             :                                    bool generatePreview) {
     274        6455 :   InjectedScript* injectedScript = nullptr;
     275       12910 :   findInjectedScript(InspectedContext::contextId(context), injectedScript);
     276        6455 :   if (!injectedScript) return nullptr;
     277        6455 :   std::unique_ptr<protocol::Runtime::RemoteObject> result;
     278       12910 :   injectedScript->wrapObject(value, groupName, false, generatePreview, &result);
     279             :   return result;
     280             : }
     281             : 
     282             : std::unique_ptr<protocol::Runtime::RemoteObject>
     283         105 : V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context,
     284             :                                   v8::Local<v8::Value> table,
     285             :                                   v8::Local<v8::Value> columns) {
     286         105 :   InjectedScript* injectedScript = nullptr;
     287         210 :   findInjectedScript(InspectedContext::contextId(context), injectedScript);
     288         105 :   if (!injectedScript) return nullptr;
     289         105 :   return injectedScript->wrapTable(table, columns);
     290             : }
     291             : 
     292         605 : void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled) {
     293         605 :   m_customObjectFormatterEnabled = enabled;
     294         605 :   int sessionId = m_sessionId;
     295             :   m_inspector->forEachContext(
     296         600 :       m_contextGroupId, [&enabled, &sessionId](InspectedContext* context) {
     297         600 :         InjectedScript* injectedScript = context->getInjectedScript(sessionId);
     298         600 :         if (injectedScript)
     299         340 :           injectedScript->setCustomObjectFormatterEnabled(enabled);
     300        1810 :       });
     301         605 : }
     302             : 
     303         595 : void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
     304             :   m_inspector->forEachContext(m_contextGroupId,
     305             :                               [&agent](InspectedContext* context) {
     306         595 :                                 agent->reportExecutionContextCreated(context);
     307        1190 :                               });
     308         595 : }
     309             : 
     310      140348 : void V8InspectorSessionImpl::dispatchProtocolMessage(
     311             :     const StringView& message) {
     312      280696 :   m_dispatcher.dispatch(protocol::StringUtil::parseJSON(message));
     313      140348 : }
     314             : 
     315          95 : std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON() {
     316          95 :   String16 json = m_state->serialize();
     317         285 :   return StringBufferImpl::adopt(json);
     318             : }
     319             : 
     320             : std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
     321           0 : V8InspectorSessionImpl::supportedDomains() {
     322             :   std::vector<std::unique_ptr<protocol::Schema::Domain>> domains =
     323           0 :       supportedDomainsImpl();
     324             :   std::vector<std::unique_ptr<protocol::Schema::API::Domain>> result;
     325           0 :   for (size_t i = 0; i < domains.size(); ++i)
     326           0 :     result.push_back(std::move(domains[i]));
     327           0 :   return result;
     328             : }
     329             : 
     330             : std::vector<std::unique_ptr<protocol::Schema::Domain>>
     331           0 : V8InspectorSessionImpl::supportedDomainsImpl() {
     332             :   std::vector<std::unique_ptr<protocol::Schema::Domain>> result;
     333             :   result.push_back(protocol::Schema::Domain::create()
     334           0 :                        .setName(protocol::Runtime::Metainfo::domainName)
     335           0 :                        .setVersion(protocol::Runtime::Metainfo::version)
     336           0 :                        .build());
     337             :   result.push_back(protocol::Schema::Domain::create()
     338           0 :                        .setName(protocol::Debugger::Metainfo::domainName)
     339           0 :                        .setVersion(protocol::Debugger::Metainfo::version)
     340           0 :                        .build());
     341             :   result.push_back(protocol::Schema::Domain::create()
     342           0 :                        .setName(protocol::Profiler::Metainfo::domainName)
     343           0 :                        .setVersion(protocol::Profiler::Metainfo::version)
     344           0 :                        .build());
     345             :   result.push_back(protocol::Schema::Domain::create()
     346           0 :                        .setName(protocol::HeapProfiler::Metainfo::domainName)
     347           0 :                        .setVersion(protocol::HeapProfiler::Metainfo::version)
     348           0 :                        .build());
     349             :   result.push_back(protocol::Schema::Domain::create()
     350           0 :                        .setName(protocol::Schema::Metainfo::domainName)
     351           0 :                        .setVersion(protocol::Schema::Metainfo::version)
     352           0 :                        .build());
     353           0 :   return result;
     354             : }
     355             : 
     356          10 : void V8InspectorSessionImpl::addInspectedObject(
     357             :     std::unique_ptr<V8InspectorSession::Inspectable> inspectable) {
     358          20 :   m_inspectedObjects.insert(m_inspectedObjects.begin(), std::move(inspectable));
     359          10 :   if (m_inspectedObjects.size() > kInspectedObjectBufferSize)
     360           0 :     m_inspectedObjects.resize(kInspectedObjectBufferSize);
     361          10 : }
     362             : 
     363          30 : V8InspectorSession::Inspectable* V8InspectorSessionImpl::inspectedObject(
     364             :     unsigned num) {
     365          60 :   if (num >= m_inspectedObjects.size()) return nullptr;
     366          20 :   return m_inspectedObjects[num].get();
     367             : }
     368             : 
     369         115 : void V8InspectorSessionImpl::schedulePauseOnNextStatement(
     370             :     const StringView& breakReason, const StringView& breakDetails) {
     371             :   m_debuggerAgent->schedulePauseOnNextStatement(
     372             :       toString16(breakReason),
     373             :       protocol::DictionaryValue::cast(
     374         690 :           protocol::StringUtil::parseJSON(breakDetails)));
     375         115 : }
     376             : 
     377          45 : void V8InspectorSessionImpl::cancelPauseOnNextStatement() {
     378          45 :   m_debuggerAgent->cancelPauseOnNextStatement();
     379          45 : }
     380             : 
     381          65 : void V8InspectorSessionImpl::breakProgram(const StringView& breakReason,
     382             :                                           const StringView& breakDetails) {
     383             :   m_debuggerAgent->breakProgram(
     384             :       toString16(breakReason),
     385             :       protocol::DictionaryValue::cast(
     386         390 :           protocol::StringUtil::parseJSON(breakDetails)));
     387          65 : }
     388             : 
     389           0 : void V8InspectorSessionImpl::setSkipAllPauses(bool skip) {
     390           0 :   m_debuggerAgent->setSkipAllPauses(skip);
     391           0 : }
     392             : 
     393           0 : void V8InspectorSessionImpl::resume() { m_debuggerAgent->resume(); }
     394             : 
     395           0 : void V8InspectorSessionImpl::stepOver() { m_debuggerAgent->stepOver(); }
     396             : 
     397             : std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
     398           0 : V8InspectorSessionImpl::searchInTextByLines(const StringView& text,
     399             :                                             const StringView& query,
     400             :                                             bool caseSensitive, bool isRegex) {
     401             :   // TODO(dgozman): search may operate on StringView and avoid copying |text|.
     402             :   std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
     403             :       searchInTextByLinesImpl(this, toString16(text), toString16(query),
     404           0 :                               caseSensitive, isRegex);
     405             :   std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>> result;
     406           0 :   for (size_t i = 0; i < matches.size(); ++i)
     407           0 :     result.push_back(std::move(matches[i]));
     408           0 :   return result;
     409             : }
     410             : 
     411             : }  // namespace v8_inspector

Generated by: LCOV version 1.10