Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Copyright (C) 2013 Google Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 #include "core/inspector/InspectorDebuggerAgent.h"
     32 
     33 #include "bindings/core/v8/ScriptDebugServer.h"
     34 #include "bindings/core/v8/ScriptRegexp.h"
     35 #include "bindings/core/v8/ScriptSourceCode.h"
     36 #include "bindings/core/v8/ScriptValue.h"
     37 #include "core/dom/Document.h"
     38 #include "core/dom/ExecutionContextTask.h"
     39 #include "core/fetch/Resource.h"
     40 #include "core/inspector/ConsoleMessage.h"
     41 #include "core/inspector/ContentSearchUtils.h"
     42 #include "core/inspector/InjectedScriptManager.h"
     43 #include "core/inspector/InspectorPageAgent.h"
     44 #include "core/inspector/InspectorState.h"
     45 #include "core/inspector/InstrumentingAgents.h"
     46 #include "core/inspector/JavaScriptCallFrame.h"
     47 #include "core/inspector/ScriptArguments.h"
     48 #include "core/inspector/ScriptAsyncCallStack.h"
     49 #include "core/inspector/ScriptCallFrame.h"
     50 #include "core/inspector/ScriptCallStack.h"
     51 #include "platform/JSONValues.h"
     52 #include "wtf/text/StringBuilder.h"
     53 #include "wtf/text/WTFString.h"
     54 
     55 using blink::TypeBuilder::Array;
     56 using blink::TypeBuilder::Debugger::BreakpointId;
     57 using blink::TypeBuilder::Debugger::CallFrame;
     58 using blink::TypeBuilder::Debugger::CollectionEntry;
     59 using blink::TypeBuilder::Debugger::ExceptionDetails;
     60 using blink::TypeBuilder::Debugger::FunctionDetails;
     61 using blink::TypeBuilder::Debugger::PromiseDetails;
     62 using blink::TypeBuilder::Debugger::ScriptId;
     63 using blink::TypeBuilder::Debugger::StackTrace;
     64 using blink::TypeBuilder::Runtime::RemoteObject;
     65 
     66 namespace {
     67 
     68 static const char v8AsyncTaskEventEnqueue[] = "enqueue";
     69 static const char v8AsyncTaskEventWillHandle[] = "willHandle";
     70 static const char v8AsyncTaskEventDidHandle[] = "didHandle";
     71 
     72 }
     73 
     74 namespace blink {
     75 
     76 namespace DebuggerAgentState {
     77 static const char debuggerEnabled[] = "debuggerEnabled";
     78 static const char javaScriptBreakpoints[] = "javaScriptBreakopints";
     79 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
     80 static const char asyncCallStackDepth[] = "asyncCallStackDepth";
     81 static const char promiseTrackerEnabled[] = "promiseTrackerEnabled";
     82 
     83 // Breakpoint properties.
     84 static const char url[] = "url";
     85 static const char isRegex[] = "isRegex";
     86 static const char lineNumber[] = "lineNumber";
     87 static const char columnNumber[] = "columnNumber";
     88 static const char condition[] = "condition";
     89 static const char isAnti[] = "isAnti";
     90 static const char skipStackPattern[] = "skipStackPattern";
     91 static const char skipContentScripts[] = "skipContentScripts";
     92 static const char skipAllPauses[] = "skipAllPauses";
     93 static const char skipAllPausesExpiresOnReload[] = "skipAllPausesExpiresOnReload";
     94 
     95 };
     96 
     97 static const int maxSkipStepInCount = 20;
     98 
     99 const char InspectorDebuggerAgent::backtraceObjectGroup[] = "backtrace";
    100 
    101 static String breakpointIdSuffix(InspectorDebuggerAgent::BreakpointSource source)
    102 {
    103     switch (source) {
    104     case InspectorDebuggerAgent::UserBreakpointSource:
    105         break;
    106     case InspectorDebuggerAgent::DebugCommandBreakpointSource:
    107         return ":debug";
    108     case InspectorDebuggerAgent::MonitorCommandBreakpointSource:
    109         return ":monitor";
    110     }
    111     return String();
    112 }
    113 
    114 static String generateBreakpointId(const String& scriptId, int lineNumber, int columnNumber, InspectorDebuggerAgent::BreakpointSource source)
    115 {
    116     return scriptId + ':' + String::number(lineNumber) + ':' + String::number(columnNumber) + breakpointIdSuffix(source);
    117 }
    118 
    119 InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedScriptManager)
    120     : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger")
    121     , m_injectedScriptManager(injectedScriptManager)
    122     , m_frontend(0)
    123     , m_pausedScriptState(nullptr)
    124     , m_javaScriptPauseScheduled(false)
    125     , m_debuggerStepScheduled(false)
    126     , m_steppingFromFramework(false)
    127     , m_pausingOnNativeEvent(false)
    128     , m_listener(nullptr)
    129     , m_skippedStepInCount(0)
    130     , m_skipAllPauses(false)
    131     , m_skipContentScripts(false)
    132     , m_asyncCallStackTracker(adoptPtrWillBeNoop(new AsyncCallStackTracker()))
    133     , m_promiseTracker(PromiseTracker::create())
    134 {
    135 }
    136 
    137 InspectorDebuggerAgent::~InspectorDebuggerAgent()
    138 {
    139 #if !ENABLE(OILPAN)
    140     ASSERT(!m_instrumentingAgents->inspectorDebuggerAgent());
    141 #endif
    142 }
    143 
    144 void InspectorDebuggerAgent::init()
    145 {
    146     // FIXME: make breakReason optional so that there was no need to init it with "other".
    147     clearBreakDetails();
    148     m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
    149 }
    150 
    151 void InspectorDebuggerAgent::enable()
    152 {
    153     m_instrumentingAgents->setInspectorDebuggerAgent(this);
    154 
    155     startListeningScriptDebugServer();
    156     // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends
    157     scriptDebugServer().setBreakpointsActivated(true);
    158 
    159     if (m_listener)
    160         m_listener->debuggerWasEnabled();
    161 }
    162 
    163 void InspectorDebuggerAgent::disable()
    164 {
    165     m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, JSONObject::create());
    166     m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
    167     m_state->setString(DebuggerAgentState::skipStackPattern, "");
    168     m_state->setBoolean(DebuggerAgentState::skipContentScripts, false);
    169     m_state->setLong(DebuggerAgentState::asyncCallStackDepth, 0);
    170     m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, false);
    171     m_instrumentingAgents->setInspectorDebuggerAgent(0);
    172 
    173     scriptDebugServer().clearBreakpoints();
    174     scriptDebugServer().clearCompiledScripts();
    175     scriptDebugServer().clearPreprocessor();
    176     stopListeningScriptDebugServer();
    177     clear();
    178 
    179     if (m_listener)
    180         m_listener->debuggerWasDisabled();
    181 
    182     m_skipAllPauses = false;
    183 }
    184 
    185 bool InspectorDebuggerAgent::enabled()
    186 {
    187     return m_state->getBoolean(DebuggerAgentState::debuggerEnabled);
    188 }
    189 
    190 void InspectorDebuggerAgent::enable(ErrorString*)
    191 {
    192     if (enabled())
    193         return;
    194 
    195     enable();
    196     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
    197 
    198     ASSERT(m_frontend);
    199 }
    200 
    201 void InspectorDebuggerAgent::disable(ErrorString*)
    202 {
    203     if (!enabled())
    204         return;
    205 
    206     disable();
    207     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
    208 }
    209 
    210 static PassOwnPtr<ScriptRegexp> compileSkipCallFramePattern(String patternText)
    211 {
    212     if (patternText.isEmpty())
    213         return nullptr;
    214     OwnPtr<ScriptRegexp> result = adoptPtr(new ScriptRegexp(patternText, TextCaseSensitive));
    215     if (!result->isValid())
    216         result.clear();
    217     return result.release();
    218 }
    219 
    220 void InspectorDebuggerAgent::restore()
    221 {
    222     if (enabled()) {
    223         m_frontend->globalObjectCleared();
    224         enable();
    225         long pauseState = m_state->getLong(DebuggerAgentState::pauseOnExceptionsState);
    226         String error;
    227         setPauseOnExceptionsImpl(&error, pauseState);
    228         m_cachedSkipStackRegExp = compileSkipCallFramePattern(m_state->getString(DebuggerAgentState::skipStackPattern));
    229         m_skipContentScripts = m_state->getBoolean(DebuggerAgentState::skipContentScripts);
    230         m_skipAllPauses = m_state->getBoolean(DebuggerAgentState::skipAllPauses);
    231         if (m_skipAllPauses && m_state->getBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload)) {
    232             m_skipAllPauses = false;
    233             m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
    234         }
    235         asyncCallStackTracker().setAsyncCallStackDepth(m_state->getLong(DebuggerAgentState::asyncCallStackDepth));
    236         promiseTracker().setEnabled(m_state->getBoolean(DebuggerAgentState::promiseTrackerEnabled));
    237     }
    238 }
    239 
    240 void InspectorDebuggerAgent::setFrontend(InspectorFrontend* frontend)
    241 {
    242     m_frontend = frontend->debugger();
    243 }
    244 
    245 void InspectorDebuggerAgent::clearFrontend()
    246 {
    247     m_frontend = 0;
    248 
    249     if (!enabled())
    250         return;
    251 
    252     disable();
    253 
    254     // FIXME: due to m_state->mute() hack in InspectorController, debuggerEnabled is actually set to false only
    255     // in InspectorState, but not in cookie. That's why after navigation debuggerEnabled will be true,
    256     // but after front-end re-open it will still be false.
    257     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
    258 }
    259 
    260 void InspectorDebuggerAgent::setBreakpointsActive(ErrorString*, bool active)
    261 {
    262     scriptDebugServer().setBreakpointsActivated(active);
    263 }
    264 
    265 void InspectorDebuggerAgent::setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload)
    266 {
    267     m_skipAllPauses = skipped;
    268     m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
    269     m_state->setBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload, asBool(untilReload));
    270 }
    271 
    272 void InspectorDebuggerAgent::pageDidCommitLoad()
    273 {
    274     if (m_state->getBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload)) {
    275         m_skipAllPauses = false;
    276         m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
    277     }
    278 }
    279 
    280 bool InspectorDebuggerAgent::isPaused()
    281 {
    282     return scriptDebugServer().isPaused();
    283 }
    284 
    285 bool InspectorDebuggerAgent::runningNestedMessageLoop()
    286 {
    287     return scriptDebugServer().runningNestedMessageLoop();
    288 }
    289 
    290 void InspectorDebuggerAgent::addMessageToConsole(ConsoleMessage* consoleMessage)
    291 {
    292     if (consoleMessage->type() == AssertMessageType && scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions)
    293         breakProgram(InspectorFrontend::Debugger::Reason::Assert, nullptr);
    294 }
    295 
    296 String InspectorDebuggerAgent::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
    297 {
    298     return scriptDebugServer().preprocessEventListener(frame, source, url, functionName);
    299 }
    300 
    301 PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
    302 {
    303     return scriptDebugServer().preprocess(frame, sourceCode);
    304 }
    305 
    306 static PassRefPtr<JSONObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, bool isRegex, bool isAnti)
    307 {
    308     RefPtr<JSONObject> breakpointObject = JSONObject::create();
    309     breakpointObject->setString(DebuggerAgentState::url, url);
    310     breakpointObject->setNumber(DebuggerAgentState::lineNumber, lineNumber);
    311     breakpointObject->setNumber(DebuggerAgentState::columnNumber, columnNumber);
    312     breakpointObject->setString(DebuggerAgentState::condition, condition);
    313     breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex);
    314     breakpointObject->setBoolean(DebuggerAgentState::isAnti, isAnti);
    315     return breakpointObject;
    316 }
    317 
    318 static String scriptSourceURL(const ScriptDebugListener::Script& script)
    319 {
    320     bool hasSourceURL = !script.sourceURL.isEmpty();
    321     return hasSourceURL ? script.sourceURL : script.url;
    322 }
    323 
    324 static bool matches(const String& url, const String& pattern, bool isRegex)
    325 {
    326     if (isRegex) {
    327         ScriptRegexp regex(pattern, TextCaseSensitive);
    328         return regex.match(url) != -1;
    329     }
    330     return url == pattern;
    331 }
    332 
    333 void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* isAntiBreakpoint, BreakpointId* outBreakpointId, RefPtr<Array<TypeBuilder::Debugger::Location> >& locations)
    334 {
    335     locations = Array<TypeBuilder::Debugger::Location>::create();
    336     if (!optionalURL == !optionalURLRegex) {
    337         *errorString = "Either url or urlRegex must be specified.";
    338         return;
    339     }
    340 
    341     bool isAntiBreakpointValue = asBool(isAntiBreakpoint);
    342 
    343     String url = optionalURL ? *optionalURL : *optionalURLRegex;
    344     int columnNumber;
    345     if (optionalColumnNumber) {
    346         columnNumber = *optionalColumnNumber;
    347         if (columnNumber < 0) {
    348             *errorString = "Incorrect column number";
    349             return;
    350         }
    351     } else {
    352         columnNumber = isAntiBreakpointValue ? -1 : 0;
    353     }
    354     String condition = optionalCondition ? *optionalCondition : "";
    355     bool isRegex = optionalURLRegex;
    356 
    357     String breakpointId = (isRegex ? "/" + url + "/" : url) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
    358     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
    359     if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end()) {
    360         *errorString = "Breakpoint at specified location already exists.";
    361         return;
    362     }
    363 
    364     breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, isRegex, isAntiBreakpointValue));
    365     m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
    366 
    367     if (!isAntiBreakpointValue) {
    368         ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
    369         for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
    370             if (!matches(scriptSourceURL(it->value), url, isRegex))
    371                 continue;
    372             RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(breakpointId, it->key, breakpoint, UserBreakpointSource);
    373             if (location)
    374                 locations->addItem(location);
    375         }
    376     }
    377     *outBreakpointId = breakpointId;
    378 }
    379 
    380 static bool parseLocation(ErrorString* errorString, PassRefPtr<JSONObject> location, String* scriptId, int* lineNumber, int* columnNumber)
    381 {
    382     if (!location->getString("scriptId", scriptId) || !location->getNumber("lineNumber", lineNumber)) {
    383         // FIXME: replace with input validation.
    384         *errorString = "scriptId and lineNumber are required.";
    385         return false;
    386     }
    387     *columnNumber = 0;
    388     location->getNumber("columnNumber", columnNumber);
    389     return true;
    390 }
    391 
    392 void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<JSONObject>& location, const String* const optionalCondition, BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Debugger::Location>& actualLocation)
    393 {
    394     String scriptId;
    395     int lineNumber;
    396     int columnNumber;
    397 
    398     if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNumber))
    399         return;
    400 
    401     String condition = optionalCondition ? *optionalCondition : emptyString();
    402 
    403     String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumber, UserBreakpointSource);
    404     if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end()) {
    405         *errorString = "Breakpoint at specified location already exists.";
    406         return;
    407     }
    408     ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
    409     actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, UserBreakpointSource);
    410     if (actualLocation)
    411         *outBreakpointId = breakpointId;
    412     else
    413         *errorString = "Could not resolve breakpoint";
    414 }
    415 
    416 void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointId)
    417 {
    418     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
    419     JSONObject::iterator it = breakpointsCookie->find(breakpointId);
    420     bool isAntibreakpoint = false;
    421     if (it != breakpointsCookie->end()) {
    422         RefPtr<JSONObject> breakpointObject = it->value->asObject();
    423         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
    424         breakpointsCookie->remove(breakpointId);
    425         m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
    426     }
    427 
    428     if (!isAntibreakpoint)
    429         removeBreakpoint(breakpointId);
    430 }
    431 
    432 void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId)
    433 {
    434     BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
    435     if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
    436         return;
    437     for (size_t i = 0; i < debugServerBreakpointIdsIterator->value.size(); ++i) {
    438         const String& debugServerBreakpointId = debugServerBreakpointIdsIterator->value[i];
    439         scriptDebugServer().removeBreakpoint(debugServerBreakpointId);
    440         m_serverBreakpoints.remove(debugServerBreakpointId);
    441     }
    442     m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator);
    443 }
    444 
    445 void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt)
    446 {
    447     if (!m_continueToLocationBreakpointId.isEmpty()) {
    448         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
    449         m_continueToLocationBreakpointId = "";
    450     }
    451 
    452     String scriptId;
    453     int lineNumber;
    454     int columnNumber;
    455 
    456     if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNumber))
    457         return;
    458 
    459     ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
    460     m_continueToLocationBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &lineNumber, &columnNumber, asBool(interstateLocationOpt));
    461     resume(errorString);
    462 }
    463 
    464 void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::Location> >& positions)
    465 {
    466     if (!isPaused() || m_currentCallStack.isEmpty()) {
    467         *errorString = "Attempt to access callframe when debugger is not on pause";
    468         return;
    469     }
    470     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
    471     if (injectedScript.isEmpty()) {
    472         *errorString = "Inspected frame has gone";
    473         return;
    474     }
    475 
    476     injectedScript.getStepInPositions(errorString, m_currentCallStack, callFrameId, positions);
    477 }
    478 
    479 void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array<CallFrame> >& callFrames, RefPtr<StackTrace>& asyncStackTrace)
    480 {
    481     if (!assertPaused(errorString))
    482         return;
    483     m_currentCallStack = scriptDebugServer().currentCallFrames();
    484     callFrames = currentCallFrames();
    485     asyncStackTrace = currentAsyncStackTrace();
    486 }
    487 
    488 PassRefPtrWillBeRawPtr<JavaScriptCallFrame> InspectorDebuggerAgent::topCallFrameSkipUnknownSources(String* scriptURL, bool* isBlackboxed)
    489 {
    490     for (int index = 0; ; ++index) {
    491         RefPtrWillBeRawPtr<JavaScriptCallFrame> frame = scriptDebugServer().callFrameNoScopes(index);
    492         if (!frame)
    493             return nullptr;
    494         ScriptsMap::iterator it = m_scripts.find(String::number(frame->sourceID()));
    495         if (it == m_scripts.end())
    496             continue;
    497         *scriptURL = scriptSourceURL(it->value);
    498         *isBlackboxed = (m_skipContentScripts && it->value.isContentScript)
    499             || (m_cachedSkipStackRegExp && !scriptURL->isEmpty() && m_cachedSkipStackRegExp->match(*scriptURL) != -1);
    500         return frame.release();
    501     }
    502 }
    503 
    504 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause()
    505 {
    506     if (m_steppingFromFramework)
    507         return ScriptDebugListener::NoSkip;
    508 
    509     // FIXME: Fast return: if (!m_skipContentScripts && !m_cachedSkipStackRegExp && !has_any_anti_breakpoint) return ScriptDebugListener::NoSkip;
    510 
    511     String topFrameScriptUrl;
    512     bool isBlackboxed = false;
    513     RefPtrWillBeRawPtr<JavaScriptCallFrame> topFrame = topCallFrameSkipUnknownSources(&topFrameScriptUrl, &isBlackboxed);
    514     if (!topFrame)
    515         return ScriptDebugListener::NoSkip;
    516     if (isBlackboxed)
    517         return ScriptDebugListener::Continue;
    518 
    519     // Match against breakpoints.
    520     if (topFrameScriptUrl.isEmpty())
    521         return ScriptDebugListener::NoSkip;
    522 
    523     // Prepare top frame parameters.
    524     int topFrameLineNumber = topFrame->line();
    525     int topFrameColumnNumber = topFrame->column();
    526 
    527     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
    528     for (JSONObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) {
    529         RefPtr<JSONObject> breakpointObject = it->value->asObject();
    530         bool isAntibreakpoint;
    531         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
    532         if (!isAntibreakpoint)
    533             continue;
    534 
    535         int breakLineNumber;
    536         breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakLineNumber);
    537         int breakColumnNumber;
    538         breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakColumnNumber);
    539 
    540         if (breakLineNumber != topFrameLineNumber)
    541             continue;
    542 
    543         if (breakColumnNumber != -1 && breakColumnNumber != topFrameColumnNumber)
    544             continue;
    545 
    546         bool isRegex;
    547         breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex);
    548         String url;
    549         breakpointObject->getString(DebuggerAgentState::url, &url);
    550         if (!matches(topFrameScriptUrl, url, isRegex))
    551             continue;
    552 
    553         return ScriptDebugListener::Continue;
    554     }
    555 
    556     return ScriptDebugListener::NoSkip;
    557 }
    558 
    559 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause()
    560 {
    561     if (m_steppingFromFramework)
    562         return ScriptDebugListener::NoSkip;
    563     // Fast return.
    564     if (!m_skipContentScripts && !m_cachedSkipStackRegExp)
    565         return ScriptDebugListener::NoSkip;
    566 
    567     String scriptUrl;
    568     bool isBlackboxed = false;
    569     RefPtrWillBeRawPtr<JavaScriptCallFrame> topFrame = topCallFrameSkipUnknownSources(&scriptUrl, &isBlackboxed);
    570     if (!topFrame || !isBlackboxed)
    571         return ScriptDebugListener::NoSkip;
    572 
    573     if (m_skippedStepInCount == 0) {
    574         m_minFrameCountForSkip = scriptDebugServer().frameCount();
    575         m_skippedStepInCount = 1;
    576         return ScriptDebugListener::StepInto;
    577     }
    578 
    579     if (m_skippedStepInCount < maxSkipStepInCount && topFrame->isAtReturn() && scriptDebugServer().frameCount() <= m_minFrameCountForSkip)
    580         m_skippedStepInCount = maxSkipStepInCount;
    581 
    582     if (m_skippedStepInCount >= maxSkipStepInCount) {
    583         if (m_pausingOnNativeEvent) {
    584             m_pausingOnNativeEvent = false;
    585             m_skippedStepInCount = 0;
    586             return ScriptDebugListener::Continue;
    587         }
    588         return ScriptDebugListener::StepOut;
    589     }
    590 
    591     ++m_skippedStepInCount;
    592     return ScriptDebugListener::StepInto;
    593 }
    594 
    595 bool InspectorDebuggerAgent::isTopCallFrameInFramework()
    596 {
    597     if (!m_skipContentScripts && !m_cachedSkipStackRegExp)
    598         return false;
    599 
    600     String scriptUrl;
    601     bool isBlackboxed = false;
    602     RefPtrWillBeRawPtr<JavaScriptCallFrame> topFrame = topCallFrameSkipUnknownSources(&scriptUrl, &isBlackboxed);
    603     return topFrame && isBlackboxed;
    604 }
    605 
    606 PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint& breakpoint, BreakpointSource source)
    607 {
    608     ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
    609     if (scriptIterator == m_scripts.end())
    610         return nullptr;
    611     Script& script = scriptIterator->value;
    612     if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint.lineNumber)
    613         return nullptr;
    614 
    615     int actualLineNumber;
    616     int actualColumnNumber;
    617     String debugServerBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false);
    618     if (debugServerBreakpointId.isEmpty())
    619         return nullptr;
    620 
    621     m_serverBreakpoints.set(debugServerBreakpointId, std::make_pair(breakpointId, source));
    622 
    623     BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
    624     if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
    625         m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).storedValue->value.append(debugServerBreakpointId);
    626     else
    627         debugServerBreakpointIdsIterator->value.append(debugServerBreakpointId);
    628 
    629     RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
    630         .setScriptId(scriptId)
    631         .setLineNumber(actualLineNumber);
    632     location->setColumnNumber(actualColumnNumber);
    633     return location;
    634 }
    635 
    636 void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& scriptId, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Array<blink::TypeBuilder::Page::SearchMatch> >& results)
    637 {
    638     ScriptsMap::iterator it = m_scripts.find(scriptId);
    639     if (it != m_scripts.end())
    640         results = ContentSearchUtils::searchInTextByLines(it->value.source, query, asBool(optionalCaseSensitive), asBool(optionalIsRegex));
    641     else
    642         *error = "No script for id: " + scriptId;
    643 }
    644 
    645 void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<StackTrace>& asyncStackTrace)
    646 {
    647     if (!scriptDebugServer().setScriptSource(scriptId, newContent, asBool(preview), error, errorData, &m_currentCallStack, &result))
    648         return;
    649 
    650     newCallFrames = currentCallFrames();
    651     asyncStackTrace = currentAsyncStackTrace();
    652 
    653     ScriptsMap::iterator it = m_scripts.find(scriptId);
    654     if (it == m_scripts.end())
    655         return;
    656     String url = it->value.url;
    657     if (url.isEmpty())
    658         return;
    659     if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent())
    660         pageAgent->addEditedResourceContent(url, newContent);
    661 }
    662 
    663 void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<StackTrace>& asyncStackTrace)
    664 {
    665     if (!isPaused() || m_currentCallStack.isEmpty()) {
    666         *errorString = "Attempt to access callframe when debugger is not on pause";
    667         return;
    668     }
    669     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
    670     if (injectedScript.isEmpty()) {
    671         *errorString = "Inspected frame has gone";
    672         return;
    673     }
    674 
    675     injectedScript.restartFrame(errorString, m_currentCallStack, callFrameId, &result);
    676     m_currentCallStack = scriptDebugServer().currentCallFrames();
    677     newCallFrames = currentCallFrames();
    678     asyncStackTrace = currentAsyncStackTrace();
    679 }
    680 
    681 void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& scriptId, String* scriptSource)
    682 {
    683     ScriptsMap::iterator it = m_scripts.find(scriptId);
    684     if (it == m_scripts.end()) {
    685         *error = "No script for id: " + scriptId;
    686         return;
    687     }
    688 
    689     String url = it->value.url;
    690     if (!url.isEmpty()) {
    691         if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent()) {
    692             bool success = pageAgent->getEditedResourceContent(url, scriptSource);
    693             if (success)
    694                 return;
    695         }
    696     }
    697     *scriptSource = it->value.source;
    698 }
    699 
    700 void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<FunctionDetails>& details)
    701 {
    702     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(functionId);
    703     if (injectedScript.isEmpty()) {
    704         *errorString = "Function object id is obsolete";
    705         return;
    706     }
    707     injectedScript.getFunctionDetails(errorString, functionId, &details);
    708 }
    709 
    710 void InspectorDebuggerAgent::getCollectionEntries(ErrorString* errorString, const String& objectId, RefPtr<TypeBuilder::Array<CollectionEntry> >& entries)
    711 {
    712     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
    713     if (injectedScript.isEmpty()) {
    714         *errorString = "Inspected frame has gone";
    715         return;
    716     }
    717     injectedScript.getCollectionEntries(errorString, objectId, &entries);
    718 }
    719 
    720 void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
    721 {
    722     if (m_javaScriptPauseScheduled || isPaused())
    723         return;
    724     m_breakReason = breakReason;
    725     m_breakAuxData = data;
    726     m_pausingOnNativeEvent = true;
    727     scriptDebugServer().setPauseOnNextStatement(true);
    728 }
    729 
    730 void InspectorDebuggerAgent::cancelPauseOnNextStatement()
    731 {
    732     if (m_javaScriptPauseScheduled || isPaused())
    733         return;
    734     clearBreakDetails();
    735     m_pausingOnNativeEvent = false;
    736     scriptDebugServer().setPauseOnNextStatement(false);
    737 }
    738 
    739 void InspectorDebuggerAgent::didInstallTimer(ExecutionContext* context, int timerId, int timeout, bool singleShot)
    740 {
    741     if (asyncCallStackTracker().isEnabled())
    742         asyncCallStackTracker().didInstallTimer(context, timerId, singleShot, scriptDebugServer().currentCallFramesForAsyncStack());
    743 }
    744 
    745 void InspectorDebuggerAgent::didRemoveTimer(ExecutionContext* context, int timerId)
    746 {
    747     if (asyncCallStackTracker().isEnabled())
    748         asyncCallStackTracker().didRemoveTimer(context, timerId);
    749 }
    750 
    751 bool InspectorDebuggerAgent::willFireTimer(ExecutionContext* context, int timerId)
    752 {
    753     if (asyncCallStackTracker().isEnabled())
    754         asyncCallStackTracker().willFireTimer(context, timerId);
    755     return true;
    756 }
    757 
    758 void InspectorDebuggerAgent::didFireTimer()
    759 {
    760     if (asyncCallStackTracker().isEnabled())
    761         asyncCallStackTracker().didFireAsyncCall();
    762     cancelPauseOnNextStatement();
    763 }
    764 
    765 void InspectorDebuggerAgent::didRequestAnimationFrame(Document* document, int callbackId)
    766 {
    767     if (asyncCallStackTracker().isEnabled())
    768         asyncCallStackTracker().didRequestAnimationFrame(document, callbackId, scriptDebugServer().currentCallFramesForAsyncStack());
    769 }
    770 
    771 void InspectorDebuggerAgent::didCancelAnimationFrame(Document* document, int callbackId)
    772 {
    773     if (asyncCallStackTracker().isEnabled())
    774         asyncCallStackTracker().didCancelAnimationFrame(document, callbackId);
    775 }
    776 
    777 bool InspectorDebuggerAgent::willFireAnimationFrame(Document* document, int callbackId)
    778 {
    779     if (asyncCallStackTracker().isEnabled())
    780         asyncCallStackTracker().willFireAnimationFrame(document, callbackId);
    781     return true;
    782 }
    783 
    784 void InspectorDebuggerAgent::didFireAnimationFrame()
    785 {
    786     if (asyncCallStackTracker().isEnabled())
    787         asyncCallStackTracker().didFireAsyncCall();
    788 }
    789 
    790 void InspectorDebuggerAgent::didEnqueueEvent(EventTarget* eventTarget, Event* event)
    791 {
    792     if (asyncCallStackTracker().isEnabled())
    793         asyncCallStackTracker().didEnqueueEvent(eventTarget, event, scriptDebugServer().currentCallFramesForAsyncStack());
    794 }
    795 
    796 void InspectorDebuggerAgent::didRemoveEvent(EventTarget* eventTarget, Event* event)
    797 {
    798     if (asyncCallStackTracker().isEnabled())
    799         asyncCallStackTracker().didRemoveEvent(eventTarget, event);
    800 }
    801 
    802 void InspectorDebuggerAgent::willHandleEvent(EventTarget* eventTarget, Event* event, EventListener* listener, bool useCapture)
    803 {
    804     if (asyncCallStackTracker().isEnabled())
    805         asyncCallStackTracker().willHandleEvent(eventTarget, event, listener, useCapture);
    806 }
    807 
    808 void InspectorDebuggerAgent::didHandleEvent()
    809 {
    810     if (asyncCallStackTracker().isEnabled())
    811         asyncCallStackTracker().didFireAsyncCall();
    812     cancelPauseOnNextStatement();
    813 }
    814 
    815 void InspectorDebuggerAgent::willLoadXHR(XMLHttpRequest* xhr, ThreadableLoaderClient*, const AtomicString&, const KURL&, bool async, PassRefPtr<FormData>, const HTTPHeaderMap&, bool)
    816 {
    817     if (asyncCallStackTracker().isEnabled() && async)
    818         asyncCallStackTracker().willLoadXHR(xhr, scriptDebugServer().currentCallFramesForAsyncStack());
    819 }
    820 
    821 void InspectorDebuggerAgent::didDispatchXHRLoadendEvent(XMLHttpRequest* xhr)
    822 {
    823     if (asyncCallStackTracker().isEnabled())
    824         asyncCallStackTracker().didLoadXHR(xhr);
    825 }
    826 
    827 void InspectorDebuggerAgent::didEnqueueMutationRecord(ExecutionContext* context, MutationObserver* observer)
    828 {
    829     if (asyncCallStackTracker().isEnabled() && !asyncCallStackTracker().hasEnqueuedMutationRecord(context, observer))
    830         asyncCallStackTracker().didEnqueueMutationRecord(context, observer, scriptDebugServer().currentCallFramesForAsyncStack());
    831 }
    832 
    833 void InspectorDebuggerAgent::didClearAllMutationRecords(ExecutionContext* context, MutationObserver* observer)
    834 {
    835     if (asyncCallStackTracker().isEnabled())
    836         asyncCallStackTracker().didClearAllMutationRecords(context, observer);
    837 }
    838 
    839 void InspectorDebuggerAgent::willDeliverMutationRecords(ExecutionContext* context, MutationObserver* observer)
    840 {
    841     if (asyncCallStackTracker().isEnabled())
    842         asyncCallStackTracker().willDeliverMutationRecords(context, observer);
    843 }
    844 
    845 void InspectorDebuggerAgent::didDeliverMutationRecords()
    846 {
    847     if (asyncCallStackTracker().isEnabled())
    848         asyncCallStackTracker().didFireAsyncCall();
    849 }
    850 
    851 void InspectorDebuggerAgent::didPostExecutionContextTask(ExecutionContext* context, ExecutionContextTask* task)
    852 {
    853     if (asyncCallStackTracker().isEnabled() && !task->taskNameForInstrumentation().isEmpty())
    854         asyncCallStackTracker().didPostExecutionContextTask(context, task, scriptDebugServer().currentCallFramesForAsyncStack());
    855 }
    856 
    857 void InspectorDebuggerAgent::didKillAllExecutionContextTasks(ExecutionContext* context)
    858 {
    859     if (asyncCallStackTracker().isEnabled())
    860         asyncCallStackTracker().didKillAllExecutionContextTasks(context);
    861 }
    862 
    863 void InspectorDebuggerAgent::willPerformExecutionContextTask(ExecutionContext* context, ExecutionContextTask* task)
    864 {
    865     if (asyncCallStackTracker().isEnabled())
    866         asyncCallStackTracker().willPerformExecutionContextTask(context, task);
    867 }
    868 
    869 void InspectorDebuggerAgent::didPerformExecutionContextTask()
    870 {
    871     if (asyncCallStackTracker().isEnabled())
    872         asyncCallStackTracker().didFireAsyncCall();
    873 }
    874 
    875 int InspectorDebuggerAgent::traceAsyncOperationStarting(ExecutionContext* context, const String& operationName, int prevOperationId)
    876 {
    877     if (!asyncCallStackTracker().isEnabled())
    878         return 0;
    879     if (prevOperationId)
    880         asyncCallStackTracker().traceAsyncOperationCompleted(context, prevOperationId);
    881     return asyncCallStackTracker().traceAsyncOperationStarting(context, operationName, scriptDebugServer().currentCallFramesForAsyncStack());
    882 }
    883 
    884 void InspectorDebuggerAgent::traceAsyncOperationCompleted(ExecutionContext* context, int operationId)
    885 {
    886     if (asyncCallStackTracker().isEnabled())
    887         asyncCallStackTracker().traceAsyncOperationCompleted(context, operationId);
    888 }
    889 
    890 void InspectorDebuggerAgent::traceAsyncOperationCompletedCallbackStarting(ExecutionContext* context, int operationId)
    891 {
    892     if (!asyncCallStackTracker().isEnabled())
    893         return;
    894     asyncCallStackTracker().traceAsyncCallbackStarting(context, operationId);
    895     asyncCallStackTracker().traceAsyncOperationCompleted(context, operationId);
    896 }
    897 
    898 void InspectorDebuggerAgent::traceAsyncCallbackStarting(ExecutionContext* context, int operationId)
    899 {
    900     if (asyncCallStackTracker().isEnabled())
    901         asyncCallStackTracker().traceAsyncCallbackStarting(context, operationId);
    902 }
    903 
    904 void InspectorDebuggerAgent::traceAsyncCallbackCompleted()
    905 {
    906     if (asyncCallStackTracker().isEnabled())
    907         asyncCallStackTracker().didFireAsyncCall();
    908 }
    909 
    910 bool InspectorDebuggerAgent::v8AsyncTaskEventsEnabled() const
    911 {
    912     return asyncCallStackTracker().isEnabled();
    913 }
    914 
    915 void InspectorDebuggerAgent::didReceiveV8AsyncTaskEvent(ExecutionContext* context, const String& eventType, const String& eventName, int id)
    916 {
    917     ASSERT(asyncCallStackTracker().isEnabled());
    918     if (eventType == v8AsyncTaskEventEnqueue)
    919         asyncCallStackTracker().didEnqueueV8AsyncTask(context, eventName, id, scriptDebugServer().currentCallFramesForAsyncStack());
    920     else if (eventType == v8AsyncTaskEventWillHandle)
    921         asyncCallStackTracker().willHandleV8AsyncTask(context, eventName, id);
    922     else if (eventType == v8AsyncTaskEventDidHandle)
    923         asyncCallStackTracker().didFireAsyncCall();
    924     else
    925         ASSERT_NOT_REACHED();
    926 }
    927 
    928 bool InspectorDebuggerAgent::v8PromiseEventsEnabled() const
    929 {
    930     return promiseTracker().isEnabled() || (m_listener && m_listener->canPauseOnPromiseEvent());
    931 }
    932 
    933 void InspectorDebuggerAgent::didReceiveV8PromiseEvent(ScriptState* scriptState, v8::Handle<v8::Object> promise, v8::Handle<v8::Value> parentPromise, int status)
    934 {
    935     if (promiseTracker().isEnabled())
    936         promiseTracker().didReceiveV8PromiseEvent(scriptState, promise, parentPromise, status);
    937     if (!m_listener)
    938         return;
    939     if (!parentPromise.IsEmpty() && parentPromise->IsObject())
    940         return;
    941     if (status < 0)
    942         m_listener->didRejectPromise();
    943     else if (status > 0)
    944         m_listener->didResolvePromise();
    945     else
    946         m_listener->didCreatePromise();
    947 }
    948 
    949 void InspectorDebuggerAgent::pause(ErrorString*)
    950 {
    951     if (m_javaScriptPauseScheduled || isPaused())
    952         return;
    953     clearBreakDetails();
    954     m_javaScriptPauseScheduled = true;
    955     scriptDebugServer().setPauseOnNextStatement(true);
    956 }
    957 
    958 void InspectorDebuggerAgent::resume(ErrorString* errorString)
    959 {
    960     if (!assertPaused(errorString))
    961         return;
    962     m_debuggerStepScheduled = false;
    963     m_steppingFromFramework = false;
    964     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
    965     scriptDebugServer().continueProgram();
    966 }
    967 
    968 void InspectorDebuggerAgent::stepOver(ErrorString* errorString)
    969 {
    970     if (!assertPaused(errorString))
    971         return;
    972     m_debuggerStepScheduled = true;
    973     m_steppingFromFramework = isTopCallFrameInFramework();
    974     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
    975     scriptDebugServer().stepOverStatement();
    976 }
    977 
    978 void InspectorDebuggerAgent::stepInto(ErrorString* errorString)
    979 {
    980     if (!assertPaused(errorString))
    981         return;
    982     m_debuggerStepScheduled = true;
    983     m_steppingFromFramework = isTopCallFrameInFramework();
    984     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
    985     scriptDebugServer().stepIntoStatement();
    986     if (m_listener)
    987         m_listener->stepInto();
    988 }
    989 
    990 void InspectorDebuggerAgent::stepOut(ErrorString* errorString)
    991 {
    992     if (!assertPaused(errorString))
    993         return;
    994     m_debuggerStepScheduled = true;
    995     m_steppingFromFramework = isTopCallFrameInFramework();
    996     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
    997     scriptDebugServer().stepOutOfFunction();
    998 }
    999 
   1000 void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, const String& stringPauseState)
   1001 {
   1002     ScriptDebugServer::PauseOnExceptionsState pauseState;
   1003     if (stringPauseState == "none")
   1004         pauseState = ScriptDebugServer::DontPauseOnExceptions;
   1005     else if (stringPauseState == "all")
   1006         pauseState = ScriptDebugServer::PauseOnAllExceptions;
   1007     else if (stringPauseState == "uncaught")
   1008         pauseState = ScriptDebugServer::PauseOnUncaughtExceptions;
   1009     else {
   1010         *errorString = "Unknown pause on exceptions mode: " + stringPauseState;
   1011         return;
   1012     }
   1013     setPauseOnExceptionsImpl(errorString, pauseState);
   1014 }
   1015 
   1016 void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString, int pauseState)
   1017 {
   1018     scriptDebugServer().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState));
   1019     if (scriptDebugServer().pauseOnExceptionsState() != pauseState)
   1020         *errorString = "Internal error. Could not change pause on exceptions state";
   1021     else
   1022         m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, pauseState);
   1023 }
   1024 
   1025 void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown, RefPtr<TypeBuilder::Debugger::ExceptionDetails>& exceptionDetails)
   1026 {
   1027     if (!isPaused() || m_currentCallStack.isEmpty()) {
   1028         *errorString = "Attempt to access callframe when debugger is not on pause";
   1029         return;
   1030     }
   1031     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
   1032     if (injectedScript.isEmpty()) {
   1033         *errorString = "Inspected frame has gone";
   1034         return;
   1035     }
   1036 
   1037     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState();
   1038     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
   1039         if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions)
   1040             scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions);
   1041         muteConsole();
   1042     }
   1043 
   1044     Vector<ScriptValue> asyncCallStacks;
   1045     const AsyncCallStackTracker::AsyncCallChain* asyncChain = asyncCallStackTracker().isEnabled() ? asyncCallStackTracker().currentAsyncCallChain() : 0;
   1046     if (asyncChain) {
   1047         const AsyncCallStackTracker::AsyncCallStackVector& callStacks = asyncChain->callStacks();
   1048         asyncCallStacks.resize(callStacks.size());
   1049         AsyncCallStackTracker::AsyncCallStackVector::const_iterator it = callStacks.begin();
   1050         for (size_t i = 0; it != callStacks.end(); ++it, ++i)
   1051             asyncCallStacks[i] = (*it)->callFrames();
   1052     }
   1053 
   1054     injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, asyncCallStacks, callFrameId, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI), asBool(returnByValue), asBool(generatePreview), &result, wasThrown, &exceptionDetails);
   1055     // V8 doesn't generate afterCompile event when it's in debugger therefore there is no content of evaluated scripts on frontend
   1056     // therefore contents of the stack does not provide necessary information
   1057     if (exceptionDetails)
   1058         exceptionDetails->setStackTrace(TypeBuilder::Array<TypeBuilder::Console::CallFrame>::create());
   1059     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
   1060         unmuteConsole();
   1061         if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState)
   1062             scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState);
   1063     }
   1064 }
   1065 
   1066 void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<ScriptId>* scriptId, RefPtr<ExceptionDetails>& exceptionDetails)
   1067 {
   1068     InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
   1069     if (injectedScript.isEmpty()) {
   1070         *errorString = "Inspected frame has gone";
   1071         return;
   1072     }
   1073 
   1074     String scriptIdValue;
   1075     String exceptionDetailsText;
   1076     int lineNumberValue = 0;
   1077     int columnNumberValue = 0;
   1078     RefPtrWillBeRawPtr<ScriptCallStack> stackTraceValue;
   1079     scriptDebugServer().compileScript(injectedScript.scriptState(), expression, sourceURL, &scriptIdValue, &exceptionDetailsText, &lineNumberValue, &columnNumberValue, &stackTraceValue);
   1080     if (!scriptIdValue && !exceptionDetailsText) {
   1081         *errorString = "Script compilation failed";
   1082         return;
   1083     }
   1084     *scriptId = scriptIdValue;
   1085     if (!scriptIdValue.isEmpty())
   1086         return;
   1087 
   1088     exceptionDetails = ExceptionDetails::create().setText(exceptionDetailsText);
   1089     exceptionDetails->setLine(lineNumberValue);
   1090     exceptionDetails->setColumn(columnNumberValue);
   1091     if (stackTraceValue && stackTraceValue->size() > 0)
   1092         exceptionDetails->setStackTrace(stackTraceValue->buildInspectorArray());
   1093 }
   1094 
   1095 void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<RemoteObject>& result, RefPtr<ExceptionDetails>& exceptionDetails)
   1096 {
   1097     InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
   1098     if (injectedScript.isEmpty()) {
   1099         *errorString = "Inspected frame has gone";
   1100         return;
   1101     }
   1102 
   1103     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState();
   1104     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
   1105         if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions)
   1106             scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions);
   1107         muteConsole();
   1108     }
   1109 
   1110     ScriptValue value;
   1111     bool wasThrownValue;
   1112     String exceptionDetailsText;
   1113     int lineNumberValue = 0;
   1114     int columnNumberValue = 0;
   1115     RefPtrWillBeRawPtr<ScriptCallStack> stackTraceValue;
   1116     scriptDebugServer().runScript(injectedScript.scriptState(), scriptId, &value, &wasThrownValue, &exceptionDetailsText, &lineNumberValue, &columnNumberValue, &stackTraceValue);
   1117     if (value.isEmpty()) {
   1118         *errorString = "Script execution failed";
   1119         return;
   1120     }
   1121     result = injectedScript.wrapObject(value, objectGroup ? *objectGroup : "");
   1122     if (wasThrownValue) {
   1123         exceptionDetails = ExceptionDetails::create().setText(exceptionDetailsText);
   1124         exceptionDetails->setLine(lineNumberValue);
   1125         exceptionDetails->setColumn(columnNumberValue);
   1126         if (stackTraceValue && stackTraceValue->size() > 0)
   1127             exceptionDetails->setStackTrace(stackTraceValue->buildInspectorArray());
   1128     }
   1129 
   1130     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
   1131         unmuteConsole();
   1132         if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState)
   1133             scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState);
   1134     }
   1135 }
   1136 
   1137 void InspectorDebuggerAgent::setOverlayMessage(ErrorString*, const String*)
   1138 {
   1139 }
   1140 
   1141 void InspectorDebuggerAgent::setVariableValue(ErrorString* errorString, int scopeNumber, const String& variableName, const RefPtr<JSONObject>& newValue, const String* callFrameId, const String* functionObjectId)
   1142 {
   1143     InjectedScript injectedScript;
   1144     if (callFrameId) {
   1145         if (!isPaused() || m_currentCallStack.isEmpty()) {
   1146             *errorString = "Attempt to access callframe when debugger is not on pause";
   1147             return;
   1148         }
   1149         injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*callFrameId);
   1150         if (injectedScript.isEmpty()) {
   1151             *errorString = "Inspected frame has gone";
   1152             return;
   1153         }
   1154     } else if (functionObjectId) {
   1155         injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*functionObjectId);
   1156         if (injectedScript.isEmpty()) {
   1157             *errorString = "Function object id cannot be resolved";
   1158             return;
   1159         }
   1160     } else {
   1161         *errorString = "Either call frame or function object must be specified";
   1162         return;
   1163     }
   1164     String newValueString = newValue->toJSONString();
   1165 
   1166     injectedScript.setVariableValue(errorString, m_currentCallStack, callFrameId, functionObjectId, scopeNumber, variableName, newValueString);
   1167 }
   1168 
   1169 void InspectorDebuggerAgent::skipStackFrames(ErrorString* errorString, const String* pattern, const bool* skipContentScripts)
   1170 {
   1171     OwnPtr<ScriptRegexp> compiled;
   1172     String patternValue = pattern ? *pattern : "";
   1173     if (!patternValue.isEmpty()) {
   1174         compiled = compileSkipCallFramePattern(patternValue);
   1175         if (!compiled) {
   1176             *errorString = "Invalid regular expression";
   1177             return;
   1178         }
   1179     }
   1180     m_state->setString(DebuggerAgentState::skipStackPattern, patternValue);
   1181     m_cachedSkipStackRegExp = compiled.release();
   1182     m_skipContentScripts = asBool(skipContentScripts);
   1183     m_state->setBoolean(DebuggerAgentState::skipContentScripts, m_skipContentScripts);
   1184 }
   1185 
   1186 void InspectorDebuggerAgent::setAsyncCallStackDepth(ErrorString*, int depth)
   1187 {
   1188     m_state->setLong(DebuggerAgentState::asyncCallStackDepth, depth);
   1189     asyncCallStackTracker().setAsyncCallStackDepth(depth);
   1190 }
   1191 
   1192 void InspectorDebuggerAgent::enablePromiseTracker(ErrorString*)
   1193 {
   1194     m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, true);
   1195     promiseTracker().setEnabled(true);
   1196 }
   1197 
   1198 void InspectorDebuggerAgent::disablePromiseTracker(ErrorString*)
   1199 {
   1200     m_state->setBoolean(DebuggerAgentState::promiseTrackerEnabled, false);
   1201     promiseTracker().setEnabled(false);
   1202 }
   1203 
   1204 void InspectorDebuggerAgent::getPromises(ErrorString* errorString, RefPtr<Array<PromiseDetails> >& promises)
   1205 {
   1206     if (!promiseTracker().isEnabled()) {
   1207         *errorString = "Promise tracking is disabled";
   1208         return;
   1209     }
   1210     promises = promiseTracker().promises();
   1211 }
   1212 
   1213 void InspectorDebuggerAgent::getPromiseById(ErrorString* errorString, int promiseId, const String* objectGroup, RefPtr<RemoteObject>& promise)
   1214 {
   1215     if (!promiseTracker().isEnabled()) {
   1216         *errorString = "Promise tracking is disabled";
   1217         return;
   1218     }
   1219     ScriptValue value = promiseTracker().promiseById(promiseId);
   1220     if (value.isEmpty()) {
   1221         *errorString = "Promise with specified ID not found.";
   1222         return;
   1223     }
   1224     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(value.scriptState());
   1225     promise = injectedScript.wrapObject(value, objectGroup ? *objectGroup : "");
   1226 }
   1227 
   1228 void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
   1229 {
   1230     if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions) {
   1231         RefPtr<JSONObject> directive = JSONObject::create();
   1232         directive->setString("directiveText", directiveText);
   1233         breakProgram(InspectorFrontend::Debugger::Reason::CSPViolation, directive.release());
   1234     }
   1235 }
   1236 
   1237 PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames()
   1238 {
   1239     if (!m_pausedScriptState || m_currentCallStack.isEmpty())
   1240         return Array<CallFrame>::create();
   1241     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState.get());
   1242     if (injectedScript.isEmpty()) {
   1243         ASSERT_NOT_REACHED();
   1244         return Array<CallFrame>::create();
   1245     }
   1246     return injectedScript.wrapCallFrames(m_currentCallStack, 0);
   1247 }
   1248 
   1249 PassRefPtr<StackTrace> InspectorDebuggerAgent::currentAsyncStackTrace()
   1250 {
   1251     if (!m_pausedScriptState || !asyncCallStackTracker().isEnabled())
   1252         return nullptr;
   1253     const AsyncCallStackTracker::AsyncCallChain* chain = asyncCallStackTracker().currentAsyncCallChain();
   1254     if (!chain)
   1255         return nullptr;
   1256     const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callStacks();
   1257     if (callStacks.isEmpty())
   1258         return nullptr;
   1259     RefPtr<StackTrace> result;
   1260     int asyncOrdinal = callStacks.size();
   1261     for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin(); it != callStacks.rend(); ++it, --asyncOrdinal) {
   1262         ScriptValue callFrames = (*it)->callFrames();
   1263         ScriptState* scriptState = callFrames.scriptState();
   1264         InjectedScript injectedScript = scriptState ? m_injectedScriptManager->injectedScriptFor(scriptState) : InjectedScript();
   1265         if (injectedScript.isEmpty()) {
   1266             result.clear();
   1267             continue;
   1268         }
   1269         RefPtr<StackTrace> next = StackTrace::create()
   1270             .setCallFrames(injectedScript.wrapCallFrames(callFrames, asyncOrdinal))
   1271             .release();
   1272         next->setDescription((*it)->description());
   1273         if (result)
   1274             next->setAsyncStackTrace(result.release());
   1275         result.swap(next);
   1276     }
   1277     return result.release();
   1278 }
   1279 
   1280 static PassRefPtrWillBeRawPtr<ScriptCallStack> toScriptCallStack(JavaScriptCallFrame* callFrame)
   1281 {
   1282     Vector<ScriptCallFrame> frames;
   1283     for (; callFrame; callFrame = callFrame->caller()) {
   1284         StringBuilder stringBuilder;
   1285         stringBuilder.appendNumber(callFrame->sourceID());
   1286         String scriptId = stringBuilder.toString();
   1287         // FIXME(WK62725): Debugger line/column are 0-based, while console ones are 1-based.
   1288         int line = callFrame->line() + 1;
   1289         int column = callFrame->column() + 1;
   1290         frames.append(ScriptCallFrame(callFrame->functionName(), scriptId, callFrame->scriptName(), line, column));
   1291     }
   1292     return ScriptCallStack::create(frames);
   1293 }
   1294 
   1295 PassRefPtrWillBeRawPtr<ScriptAsyncCallStack> InspectorDebuggerAgent::currentAsyncStackTraceForConsole()
   1296 {
   1297     if (!asyncCallStackTracker().isEnabled())
   1298         return nullptr;
   1299     const AsyncCallStackTracker::AsyncCallChain* chain = asyncCallStackTracker().currentAsyncCallChain();
   1300     if (!chain)
   1301         return nullptr;
   1302     const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callStacks();
   1303     if (callStacks.isEmpty())
   1304         return nullptr;
   1305     RefPtrWillBeRawPtr<ScriptAsyncCallStack> result = nullptr;
   1306     for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin(); it != callStacks.rend(); ++it) {
   1307         RefPtrWillBeRawPtr<JavaScriptCallFrame> callFrame = ScriptDebugServer::toJavaScriptCallFrameUnsafe((*it)->callFrames());
   1308         if (!callFrame)
   1309             break;
   1310         result = ScriptAsyncCallStack::create((*it)->description(), toScriptCallStack(callFrame.get()), result.release());
   1311     }
   1312     return result.release();
   1313 }
   1314 
   1315 String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script, CompileResult compileResult)
   1316 {
   1317     bool hasSyntaxError = compileResult != CompileSuccess;
   1318     if (hasSyntaxError) {
   1319         bool deprecated;
   1320         String sourceMapURL = ContentSearchUtils::findSourceMapURL(script.source, ContentSearchUtils::JavaScriptMagicComment, &deprecated);
   1321         if (!sourceMapURL.isEmpty())
   1322             return sourceMapURL;
   1323     }
   1324 
   1325     if (!script.sourceMappingURL.isEmpty())
   1326         return script.sourceMappingURL;
   1327 
   1328     if (script.url.isEmpty())
   1329         return String();
   1330 
   1331     InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent();
   1332     if (!pageAgent)
   1333         return String();
   1334     return pageAgent->resourceSourceMapURL(script.url);
   1335 }
   1336 
   1337 // ScriptDebugListener functions
   1338 
   1339 void InspectorDebuggerAgent::didParseSource(const String& scriptId, const Script& parsedScript, CompileResult compileResult)
   1340 {
   1341     Script script = parsedScript;
   1342     const bool* isContentScript = script.isContentScript ? &script.isContentScript : 0;
   1343 
   1344     bool hasSyntaxError = compileResult != CompileSuccess;
   1345     if (hasSyntaxError) {
   1346         bool deprecated;
   1347         script.sourceURL = ContentSearchUtils::findSourceURL(script.source, ContentSearchUtils::JavaScriptMagicComment, &deprecated);
   1348     }
   1349 
   1350     bool hasSourceURL = !script.sourceURL.isEmpty();
   1351     String scriptURL = hasSourceURL ? script.sourceURL : script.url;
   1352 
   1353     String sourceMapURL = sourceMapURLForScript(script, compileResult);
   1354     String* sourceMapURLParam = sourceMapURL.isNull() ? 0 : &sourceMapURL;
   1355 
   1356     bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : 0;
   1357     if (!hasSyntaxError)
   1358         m_frontend->scriptParsed(scriptId, scriptURL, script.startLine, script.startColumn, script.endLine, script.endColumn, isContentScript, sourceMapURLParam, hasSourceURLParam);
   1359     else
   1360         m_frontend->scriptFailedToParse(scriptId, scriptURL, script.startLine, script.startColumn, script.endLine, script.endColumn, isContentScript, sourceMapURLParam, hasSourceURLParam);
   1361 
   1362     m_scripts.set(scriptId, script);
   1363 
   1364     if (scriptURL.isEmpty() || hasSyntaxError)
   1365         return;
   1366 
   1367     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
   1368     for (JSONObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) {
   1369         RefPtr<JSONObject> breakpointObject = it->value->asObject();
   1370         bool isAntibreakpoint;
   1371         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
   1372         if (isAntibreakpoint)
   1373             continue;
   1374         bool isRegex;
   1375         breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex);
   1376         String url;
   1377         breakpointObject->getString(DebuggerAgentState::url, &url);
   1378         if (!matches(scriptURL, url, isRegex))
   1379             continue;
   1380         ScriptBreakpoint breakpoint;
   1381         breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.lineNumber);
   1382         breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoint.columnNumber);
   1383         breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.condition);
   1384         RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(it->key, scriptId, breakpoint, UserBreakpointSource);
   1385         if (location)
   1386             m_frontend->breakpointResolved(it->key, location);
   1387     }
   1388 }
   1389 
   1390 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
   1391 {
   1392     ScriptDebugListener::SkipPauseRequest result;
   1393     if (callFrames.isEmpty())
   1394         result = ScriptDebugListener::Continue; // Skip pauses inside V8 internal scripts and on syntax errors.
   1395     else if (m_javaScriptPauseScheduled)
   1396         result = ScriptDebugListener::NoSkip; // Don't skip explicit pause requests from front-end.
   1397     else if (m_skipAllPauses)
   1398         result = ScriptDebugListener::Continue;
   1399     else if (!hitBreakpoints.isEmpty())
   1400         result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints even if set in frameworks.
   1401     else if (!exception.isEmpty())
   1402         result = shouldSkipExceptionPause();
   1403     else if (m_debuggerStepScheduled || m_pausingOnNativeEvent)
   1404         result = shouldSkipStepPause();
   1405     else
   1406         result = ScriptDebugListener::NoSkip;
   1407 
   1408     if (result != ScriptDebugListener::NoSkip)
   1409         return result;
   1410 
   1411     ASSERT(scriptState && !m_pausedScriptState);
   1412     m_pausedScriptState = scriptState;
   1413     m_currentCallStack = callFrames;
   1414 
   1415     if (!exception.isEmpty()) {
   1416         InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
   1417         if (!injectedScript.isEmpty()) {
   1418             m_breakReason = InspectorFrontend::Debugger::Reason::Exception;
   1419             m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
   1420             // m_breakAuxData might be null after this.
   1421         }
   1422     }
   1423 
   1424     RefPtr<Array<String> > hitBreakpointIds = Array<String>::create();
   1425 
   1426     for (Vector<String>::const_iterator i = hitBreakpoints.begin(); i != hitBreakpoints.end(); ++i) {
   1427         DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIterator = m_serverBreakpoints.find(*i);
   1428         if (breakpointIterator != m_serverBreakpoints.end()) {
   1429             const String& localId = breakpointIterator->value.first;
   1430             hitBreakpointIds->addItem(localId);
   1431 
   1432             BreakpointSource source = breakpointIterator->value.second;
   1433             if (m_breakReason == InspectorFrontend::Debugger::Reason::Other && source == DebugCommandBreakpointSource)
   1434                 m_breakReason = InspectorFrontend::Debugger::Reason::DebugCommand;
   1435         }
   1436     }
   1437 
   1438     m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds, currentAsyncStackTrace());
   1439     m_javaScriptPauseScheduled = false;
   1440     m_debuggerStepScheduled = false;
   1441     m_steppingFromFramework = false;
   1442     m_pausingOnNativeEvent = false;
   1443     m_skippedStepInCount = 0;
   1444 
   1445     if (!m_continueToLocationBreakpointId.isEmpty()) {
   1446         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
   1447         m_continueToLocationBreakpointId = "";
   1448     }
   1449     if (m_listener)
   1450         m_listener->didPause();
   1451     return result;
   1452 }
   1453 
   1454 void InspectorDebuggerAgent::didContinue()
   1455 {
   1456     m_pausedScriptState = nullptr;
   1457     m_currentCallStack = ScriptValue();
   1458     clearBreakDetails();
   1459     m_frontend->resumed();
   1460 }
   1461 
   1462 bool InspectorDebuggerAgent::canBreakProgram()
   1463 {
   1464     return scriptDebugServer().canBreakProgram();
   1465 }
   1466 
   1467 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
   1468 {
   1469     if (m_skipAllPauses)
   1470         return;
   1471     m_breakReason = breakReason;
   1472     m_breakAuxData = data;
   1473     m_debuggerStepScheduled = false;
   1474     m_steppingFromFramework = false;
   1475     m_pausingOnNativeEvent = false;
   1476     scriptDebugServer().breakProgram();
   1477 }
   1478 
   1479 void InspectorDebuggerAgent::clear()
   1480 {
   1481     m_pausedScriptState = nullptr;
   1482     m_currentCallStack = ScriptValue();
   1483     m_scripts.clear();
   1484     m_breakpointIdToDebugServerBreakpointIds.clear();
   1485     asyncCallStackTracker().clear();
   1486     promiseTracker().clear();
   1487     m_continueToLocationBreakpointId = String();
   1488     clearBreakDetails();
   1489     m_javaScriptPauseScheduled = false;
   1490     m_debuggerStepScheduled = false;
   1491     m_steppingFromFramework = false;
   1492     m_pausingOnNativeEvent = false;
   1493     ErrorString error;
   1494     setOverlayMessage(&error, 0);
   1495 }
   1496 
   1497 bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
   1498 {
   1499     if (!m_pausedScriptState) {
   1500         *errorString = "Can only perform operation while paused.";
   1501         return false;
   1502     }
   1503     return true;
   1504 }
   1505 
   1506 void InspectorDebuggerAgent::clearBreakDetails()
   1507 {
   1508     m_breakReason = InspectorFrontend::Debugger::Reason::Other;
   1509     m_breakAuxData = nullptr;
   1510 }
   1511 
   1512 void InspectorDebuggerAgent::setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source, const String& condition)
   1513 {
   1514     String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumber, source);
   1515     ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
   1516     resolveBreakpoint(breakpointId, scriptId, breakpoint, source);
   1517 }
   1518 
   1519 void InspectorDebuggerAgent::removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source)
   1520 {
   1521     removeBreakpoint(generateBreakpointId(scriptId, lineNumber, columnNumber, source));
   1522 }
   1523 
   1524 void InspectorDebuggerAgent::reset()
   1525 {
   1526     m_scripts.clear();
   1527     m_breakpointIdToDebugServerBreakpointIds.clear();
   1528     asyncCallStackTracker().clear();
   1529     promiseTracker().clear();
   1530     if (m_frontend)
   1531         m_frontend->globalObjectCleared();
   1532 }
   1533 
   1534 void InspectorDebuggerAgent::trace(Visitor* visitor)
   1535 {
   1536     visitor->trace(m_injectedScriptManager);
   1537     visitor->trace(m_listener);
   1538     visitor->trace(m_asyncCallStackTracker);
   1539 #if ENABLE(OILPAN)
   1540     visitor->trace(m_promiseTracker);
   1541 #endif
   1542     InspectorBaseAgent::trace(visitor);
   1543 }
   1544 
   1545 } // namespace blink
   1546