LCOV - code coverage report
Current view: top level - src/inspector - v8-inspector-impl.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 116 144 80.6 %
Date: 2017-04-26 Functions: 31 39 79.5 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2010-2011 Google Inc. All rights reserved.
       3             :  *
       4             :  * Redistribution and use in source and binary forms, with or without
       5             :  * modification, are permitted provided that the following conditions are
       6             :  * met:
       7             :  *
       8             :  *     * Redistributions of source code must retain the above copyright
       9             :  * notice, this list of conditions and the following disclaimer.
      10             :  *     * Redistributions in binary form must reproduce the above
      11             :  * copyright notice, this list of conditions and the following disclaimer
      12             :  * in the documentation and/or other materials provided with the
      13             :  * distribution.
      14             :  *     * Neither the name of Google Inc. nor the names of its
      15             :  * contributors may be used to endorse or promote products derived from
      16             :  * this software without specific prior written permission.
      17             :  *
      18             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      21             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      22             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      23             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      24             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      25             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      26             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      27             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      28             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29             :  */
      30             : 
      31             : #include "src/inspector/v8-inspector-impl.h"
      32             : 
      33             : #include "src/inspector/inspected-context.h"
      34             : #include "src/inspector/string-util.h"
      35             : #include "src/inspector/v8-console-agent-impl.h"
      36             : #include "src/inspector/v8-console-message.h"
      37             : #include "src/inspector/v8-console.h"
      38             : #include "src/inspector/v8-debugger-agent-impl.h"
      39             : #include "src/inspector/v8-debugger.h"
      40             : #include "src/inspector/v8-inspector-session-impl.h"
      41             : #include "src/inspector/v8-profiler-agent-impl.h"
      42             : #include "src/inspector/v8-runtime-agent-impl.h"
      43             : #include "src/inspector/v8-stack-trace-impl.h"
      44             : 
      45             : namespace v8_inspector {
      46             : 
      47        4543 : std::unique_ptr<V8Inspector> V8Inspector::create(v8::Isolate* isolate,
      48             :                                                  V8InspectorClient* client) {
      49        9086 :   return std::unique_ptr<V8Inspector>(new V8InspectorImpl(isolate, client));
      50             : }
      51             : 
      52        4543 : V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate,
      53             :                                  V8InspectorClient* client)
      54             :     : m_isolate(isolate),
      55             :       m_client(client),
      56        4543 :       m_debugger(new V8Debugger(isolate, this)),
      57             :       m_capturingStackTracesCount(0),
      58             :       m_lastExceptionId(0),
      59       31801 :       m_lastContextId(0) {
      60        4543 :   v8::debug::SetConsoleDelegate(m_isolate, console());
      61        4543 : }
      62             : 
      63        9086 : V8InspectorImpl::~V8InspectorImpl() {
      64        4543 :   v8::debug::SetConsoleDelegate(m_isolate, nullptr);
      65        9086 : }
      66             : 
      67      780795 : int V8InspectorImpl::contextGroupId(v8::Local<v8::Context> context) {
      68     1561590 :   return contextGroupId(InspectedContext::contextId(context));
      69             : }
      70             : 
      71       97888 : int V8InspectorImpl::contextGroupId(int contextId) {
      72             :   protocol::HashMap<int, int>::iterator it =
      73             :       m_contextIdToGroupIdMap.find(contextId);
      74      878683 :   return it != m_contextIdToGroupIdMap.end() ? it->second : 0;
      75             : }
      76             : 
      77      195694 : V8DebuggerAgentImpl* V8InspectorImpl::enabledDebuggerAgentForGroup(
      78             :     int contextGroupId) {
      79      195694 :   V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
      80      195694 :   V8DebuggerAgentImpl* agent = session ? session->debuggerAgent() : nullptr;
      81      195694 :   return agent && agent->enabled() ? agent : nullptr;
      82             : }
      83             : 
      84        7304 : V8RuntimeAgentImpl* V8InspectorImpl::enabledRuntimeAgentForGroup(
      85             :     int contextGroupId) {
      86        7304 :   V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
      87       14608 :   V8RuntimeAgentImpl* agent = session ? session->runtimeAgent() : nullptr;
      88       14608 :   return agent && agent->enabled() ? agent : nullptr;
      89             : }
      90             : 
      91           0 : V8ProfilerAgentImpl* V8InspectorImpl::enabledProfilerAgentForGroup(
      92             :     int contextGroupId) {
      93           0 :   V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
      94           0 :   V8ProfilerAgentImpl* agent = session ? session->profilerAgent() : nullptr;
      95           0 :   return agent && agent->enabled() ? agent : nullptr;
      96             : }
      97             : 
      98        8594 : v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(
      99             :     v8::Local<v8::Context> context, v8::Local<v8::String> source) {
     100             :   v8::Local<v8::UnboundScript> unboundScript;
     101       17188 :   if (!v8::debug::CompileInspectorScript(m_isolate, source)
     102       17188 :            .ToLocal(&unboundScript))
     103           0 :     return v8::MaybeLocal<v8::Value>();
     104             :   v8::MicrotasksScope microtasksScope(m_isolate,
     105        8594 :                                       v8::MicrotasksScope::kDoNotRunMicrotasks);
     106             :   v8::Context::Scope contextScope(context);
     107       25782 :   return unboundScript->BindToCurrentContext()->Run(context);
     108             : }
     109             : 
     110        5255 : v8::MaybeLocal<v8::Script> V8InspectorImpl::compileScript(
     111             :     v8::Local<v8::Context> context, const String16& code,
     112             :     const String16& fileName) {
     113             :   v8::ScriptOrigin origin(
     114             :       toV8String(m_isolate, fileName), v8::Integer::New(m_isolate, 0),
     115             :       v8::Integer::New(m_isolate, 0),
     116             :       v8::False(m_isolate),                                         // sharable
     117             :       v8::Local<v8::Integer>(), toV8String(m_isolate, String16()),  // sourceMap
     118       21020 :       v8::True(m_isolate));  // opaqueresource
     119        5255 :   v8::ScriptCompiler::Source source(toV8String(m_isolate, code), origin);
     120             :   return v8::ScriptCompiler::Compile(context, &source,
     121       10510 :                                      v8::ScriptCompiler::kNoCompileOptions);
     122             : }
     123             : 
     124         402 : void V8InspectorImpl::enableStackCapturingIfNeeded() {
     125         402 :   if (!m_capturingStackTracesCount)
     126             :     V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate,
     127         384 :                                                                 true);
     128         402 :   ++m_capturingStackTracesCount;
     129         402 : }
     130             : 
     131         402 : void V8InspectorImpl::disableStackCapturingIfNeeded() {
     132         402 :   if (!(--m_capturingStackTracesCount))
     133             :     V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate,
     134         384 :                                                                 false);
     135         402 : }
     136             : 
     137      636115 : void V8InspectorImpl::muteExceptions(int contextGroupId) {
     138      636115 :   m_muteExceptionsMap[contextGroupId]++;
     139      636115 : }
     140             : 
     141      636115 : void V8InspectorImpl::unmuteExceptions(int contextGroupId) {
     142      636115 :   m_muteExceptionsMap[contextGroupId]--;
     143      636115 : }
     144             : 
     145        7926 : V8ConsoleMessageStorage* V8InspectorImpl::ensureConsoleMessageStorage(
     146             :     int contextGroupId) {
     147             :   ConsoleStorageMap::iterator storageIt =
     148             :       m_consoleStorageMap.find(contextGroupId);
     149        7926 :   if (storageIt == m_consoleStorageMap.end())
     150             :     storageIt = m_consoleStorageMap
     151             :                     .insert(std::make_pair(
     152             :                         contextGroupId,
     153             :                         std::unique_ptr<V8ConsoleMessageStorage>(
     154         588 :                             new V8ConsoleMessageStorage(this, contextGroupId))))
     155             :                     .first;
     156        7926 :   return storageIt->second.get();
     157             : }
     158             : 
     159       22134 : bool V8InspectorImpl::hasConsoleMessageStorage(int contextGroupId) {
     160             :   ConsoleStorageMap::iterator storageIt =
     161             :       m_consoleStorageMap.find(contextGroupId);
     162       22134 :   return storageIt != m_consoleStorageMap.end();
     163             : }
     164             : 
     165          84 : std::unique_ptr<V8StackTrace> V8InspectorImpl::createStackTrace(
     166             :     v8::Local<v8::StackTrace> stackTrace) {
     167         168 :   return m_debugger->createStackTrace(stackTrace);
     168             : }
     169             : 
     170        4573 : std::unique_ptr<V8InspectorSession> V8InspectorImpl::connect(
     171             :     int contextGroupId, V8Inspector::Channel* channel,
     172             :     const StringView& state) {
     173             :   DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend());
     174             :   std::unique_ptr<V8InspectorSessionImpl> session =
     175        4573 :       V8InspectorSessionImpl::create(this, contextGroupId, channel, state);
     176        4573 :   m_sessions[contextGroupId] = session.get();
     177        4573 :   return std::move(session);
     178             : }
     179             : 
     180        4573 : void V8InspectorImpl::disconnect(V8InspectorSessionImpl* session) {
     181             :   DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end());
     182        9146 :   m_sessions.erase(session->contextGroupId());
     183        4573 : }
     184             : 
     185       55713 : InspectedContext* V8InspectorImpl::getContext(int groupId,
     186             :                                               int contextId) const {
     187       55713 :   if (!groupId || !contextId) return nullptr;
     188             : 
     189             :   ContextsByGroupMap::const_iterator contextGroupIt = m_contexts.find(groupId);
     190       55559 :   if (contextGroupIt == m_contexts.end()) return nullptr;
     191             : 
     192             :   ContextByIdMap::iterator contextIt = contextGroupIt->second->find(contextId);
     193       55559 :   if (contextIt == contextGroupIt->second->end()) return nullptr;
     194             : 
     195       55559 :   return contextIt->second.get();
     196             : }
     197             : 
     198        4579 : void V8InspectorImpl::contextCreated(const V8ContextInfo& info) {
     199        4579 :   int contextId = ++m_lastContextId;
     200        4579 :   InspectedContext* context = new InspectedContext(this, info, contextId);
     201        4579 :   m_contextIdToGroupIdMap[contextId] = info.contextGroupId;
     202             : 
     203        9158 :   ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId);
     204        4579 :   if (contextIt == m_contexts.end())
     205             :     contextIt = m_contexts
     206             :                     .insert(std::make_pair(
     207             :                         info.contextGroupId,
     208        9158 :                         std::unique_ptr<ContextByIdMap>(new ContextByIdMap())))
     209             :                     .first;
     210             :   const auto& contextById = contextIt->second;
     211             : 
     212             :   DCHECK(contextById->find(contextId) == contextById->cend());
     213             :   (*contextById)[contextId].reset(context);
     214             :   SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId);
     215        4579 :   if (sessionIt != m_sessions.end())
     216        9158 :     sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context);
     217        4579 : }
     218             : 
     219           6 : void V8InspectorImpl::contextDestroyed(v8::Local<v8::Context> context) {
     220           6 :   int contextId = InspectedContext::contextId(context);
     221           6 :   int groupId = contextGroupId(context);
     222             :   m_contextIdToGroupIdMap.erase(contextId);
     223             : 
     224             :   ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(groupId);
     225           6 :   if (storageIt != m_consoleStorageMap.end())
     226          12 :     storageIt->second->contextDestroyed(contextId);
     227             : 
     228           6 :   InspectedContext* inspectedContext = getContext(groupId, contextId);
     229           6 :   if (!inspectedContext) return;
     230             : 
     231             :   SessionMap::iterator iter = m_sessions.find(groupId);
     232           6 :   if (iter != m_sessions.end())
     233             :     iter->second->runtimeAgent()->reportExecutionContextDestroyed(
     234           6 :         inspectedContext);
     235           6 :   discardInspectedContext(groupId, contextId);
     236             : }
     237             : 
     238           0 : void V8InspectorImpl::resetContextGroup(int contextGroupId) {
     239             :   m_consoleStorageMap.erase(contextGroupId);
     240             :   m_muteExceptionsMap.erase(contextGroupId);
     241             :   SessionMap::iterator session = m_sessions.find(contextGroupId);
     242           0 :   if (session != m_sessions.end()) session->second->reset();
     243             :   m_contexts.erase(contextGroupId);
     244           0 :   m_debugger->wasmTranslation()->Clear();
     245           0 : }
     246             : 
     247           0 : void V8InspectorImpl::idleStarted() {
     248           0 :   for (auto it = m_sessions.begin(); it != m_sessions.end(); ++it) {
     249           0 :     if (it->second->profilerAgent()->idleStarted()) return;
     250             :   }
     251             : }
     252             : 
     253           0 : void V8InspectorImpl::idleFinished() {
     254           0 :   for (auto it = m_sessions.begin(); it != m_sessions.end(); ++it) {
     255           0 :     if (it->second->profilerAgent()->idleFinished()) return;
     256             :   }
     257             : }
     258             : 
     259          84 : unsigned V8InspectorImpl::exceptionThrown(
     260             :     v8::Local<v8::Context> context, const StringView& message,
     261             :     v8::Local<v8::Value> exception, const StringView& detailedMessage,
     262             :     const StringView& url, unsigned lineNumber, unsigned columnNumber,
     263             :     std::unique_ptr<V8StackTrace> stackTrace, int scriptId) {
     264          84 :   int groupId = contextGroupId(context);
     265         168 :   if (!groupId || m_muteExceptionsMap[groupId]) return 0;
     266             :   std::unique_ptr<V8StackTraceImpl> stackTraceImpl(
     267             :       static_cast<V8StackTraceImpl*>(stackTrace.release()));
     268             :   unsigned exceptionId = nextExceptionId();
     269             :   std::unique_ptr<V8ConsoleMessage> consoleMessage =
     270             :       V8ConsoleMessage::createForException(
     271          84 :           m_client->currentTimeMS(), toString16(detailedMessage),
     272             :           toString16(url), lineNumber, columnNumber, std::move(stackTraceImpl),
     273             :           scriptId, m_isolate, toString16(message),
     274         588 :           InspectedContext::contextId(context), exception, exceptionId);
     275         168 :   ensureConsoleMessageStorage(groupId)->addMessage(std::move(consoleMessage));
     276             :   return exceptionId;
     277             : }
     278             : 
     279           0 : void V8InspectorImpl::exceptionRevoked(v8::Local<v8::Context> context,
     280             :                                        unsigned exceptionId,
     281             :                                        const StringView& message) {
     282           0 :   int groupId = contextGroupId(context);
     283           0 :   if (!groupId) return;
     284             : 
     285             :   std::unique_ptr<V8ConsoleMessage> consoleMessage =
     286             :       V8ConsoleMessage::createForRevokedException(
     287           0 :           m_client->currentTimeMS(), toString16(message), exceptionId);
     288           0 :   ensureConsoleMessageStorage(groupId)->addMessage(std::move(consoleMessage));
     289             : }
     290             : 
     291           0 : std::unique_ptr<V8StackTrace> V8InspectorImpl::captureStackTrace(
     292             :     bool fullStack) {
     293           0 :   return m_debugger->captureStackTrace(fullStack);
     294             : }
     295             : 
     296        1482 : void V8InspectorImpl::asyncTaskScheduled(const StringView& taskName, void* task,
     297             :                                          bool recurring) {
     298        2964 :   m_debugger->asyncTaskScheduled(taskName, task, recurring);
     299        1482 : }
     300             : 
     301           0 : void V8InspectorImpl::asyncTaskCanceled(void* task) {
     302           0 :   m_debugger->asyncTaskCanceled(task);
     303           0 : }
     304             : 
     305        1482 : void V8InspectorImpl::asyncTaskStarted(void* task) {
     306        1482 :   m_debugger->asyncTaskStarted(task);
     307        1482 : }
     308             : 
     309        1482 : void V8InspectorImpl::asyncTaskFinished(void* task) {
     310        1482 :   m_debugger->asyncTaskFinished(task);
     311        1482 : }
     312             : 
     313           0 : void V8InspectorImpl::allAsyncTasksCanceled() {
     314           0 :   m_debugger->allAsyncTasksCanceled();
     315           0 : }
     316             : 
     317         459 : v8::Local<v8::Context> V8InspectorImpl::regexContext() {
     318         459 :   if (m_regexContext.IsEmpty())
     319         110 :     m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate));
     320         918 :   return m_regexContext.Get(m_isolate);
     321             : }
     322             : 
     323           6 : void V8InspectorImpl::discardInspectedContext(int contextGroupId,
     324             :                                               int contextId) {
     325          12 :   if (!getContext(contextGroupId, contextId)) return;
     326             :   m_contexts[contextGroupId]->erase(contextId);
     327           6 :   if (m_contexts[contextGroupId]->empty()) m_contexts.erase(contextGroupId);
     328             : }
     329             : 
     330      487628 : const V8InspectorImpl::ContextByIdMap* V8InspectorImpl::contextGroup(
     331             :     int contextGroupId) {
     332             :   ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId);
     333      975256 :   return iter == m_contexts.end() ? nullptr : iter->second.get();
     334             : }
     335             : 
     336      357280 : V8InspectorSessionImpl* V8InspectorImpl::sessionForContextGroup(
     337             :     int contextGroupId) {
     338      357280 :   if (!contextGroupId) return nullptr;
     339             :   SessionMap::iterator iter = m_sessions.find(contextGroupId);
     340      357280 :   return iter == m_sessions.end() ? nullptr : iter->second;
     341             : }
     342             : 
     343        5350 : V8Console* V8InspectorImpl::console() {
     344        5350 :   if (!m_console) m_console.reset(new V8Console(this));
     345        5350 :   return m_console.get();
     346             : }
     347             : 
     348             : }  // namespace v8_inspector

Generated by: LCOV version 1.10