Changeset 162096 in webkit


Ignore:
Timestamp:
Jan 15, 2014 3:22:39 PM (10 years ago)
Author:
BJ Burg
Message:

Web Inspector: capture probe samples on the backend
https://bugs.webkit.org/show_bug.cgi?id=126668

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

Add the 'probe' breakpoint action to the protocol. Change the setBreakpoint
commands to return a list of assigned breakpoint action identifiers
Add a type for breakpoint action identifiers. Add an event for sending
captured probe samples to the inspector frontend.

  • inspector/protocol/Debugger.json:

Source/WebCore:

Test: inspector-protocol/debugger/setProbe-multiple-actions.html

Add the probe breakpoint action type. A probe action
evaluates an expression on the script call frame, and
the result is aggregated on a per-probe basis. Each
evaluated expression result is called a probe sample.

  • bindings/js/ScriptDebugServer.cpp:

(WebCore::ScriptDebugServer::evaluateBreakpointAction): Teach
the debug server to evaluate a probe.

(WebCore::ScriptDebugServer::dispatchDidSampleProbe): Added.
(WebCore::ScriptDebugServer::handleBreakpointHit): Increment a hit count.
(WebCore::ScriptDebugServer::getActionsForBreakpoint):

  • bindings/js/ScriptDebugServer.h:
  • inspector/InspectorDebuggerAgent.cpp:

(WebCore::objectGroupForBreakpointAction): Added. Create an object
group for each breakpoint action. Currently only probes make objects.
(WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent):
(WebCore::InspectorDebuggerAgent::disable):
(WebCore::InspectorDebuggerAgent::enable): Remove stale comment.
(WebCore::breakpointActionTypeForString): Add new case.
(WebCore::InspectorDebuggerAgent::breakpointActionsFromProtocol): Make
this a member function instead of a static function, so it can increment
the breakpoint action identifier counter.
(WebCore::InspectorDebuggerAgent::setBreakpointByUrl): Propagate the
assigned breakpoint action identifiers.
(WebCore::InspectorDebuggerAgent::setBreakpoint): Propagate the
assigned breakpoint action identifiers.
(WebCore::InspectorDebuggerAgent::removeBreakpoint): Release object
groups for any actions that were associated with the removed breakpoint.
(WebCore::InspectorDebuggerAgent::didSampleProbe): Added.
(WebCore::InspectorDebuggerAgent::clearResolvedBreakpointState): Renamed from clear().
(WebCore::InspectorDebuggerAgent::didClearGlobalObject): Renamed from reset().

  • inspector/InspectorDebuggerAgent.h:
  • inspector/PageDebuggerAgent.cpp:

(WebCore::PageDebuggerAgent::didClearMainFrameWindowObject):

  • inspector/ScriptBreakpoint.h:

(WebCore::ScriptBreakpointAction::ScriptBreakpointAction): Add identifier member.

  • inspector/ScriptDebugListener.h:

Source/WebInspectorUI:

  • UserInterface/InspectorJSBackendCommands.js: Add probe enumeration value.

LayoutTests:

Add protocol tests for setting and hitting the probe breakpoint action type.

  • inspector-protocol/debugger/setBreakpoint-actions-expected.txt:
  • inspector-protocol/debugger/setBreakpoint-actions.html:
  • inspector-protocol/debugger/setProbe-multiple-actions-expected.txt: Added.
  • inspector-protocol/debugger/setProbe-multiple-actions.html: Added.
  • inspector-protocol/resources/probe-helper.js: Added.

(ProbeHelper.simplifiedProbeSample):

Location:
trunk
Files:
3 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r162088 r162096  
     12014-01-15  Brian Burg  <bburg@apple.com>
     2
     3        Web Inspector: capture probe samples on the backend
     4        https://bugs.webkit.org/show_bug.cgi?id=126668
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Add protocol tests for setting and hitting the probe breakpoint action type.
     9
     10        * inspector-protocol/debugger/setBreakpoint-actions-expected.txt:
     11        * inspector-protocol/debugger/setBreakpoint-actions.html:
     12        * inspector-protocol/debugger/setProbe-multiple-actions-expected.txt: Added.
     13        * inspector-protocol/debugger/setProbe-multiple-actions.html: Added.
     14        * inspector-protocol/resources/probe-helper.js: Added.
     15        (ProbeHelper.simplifiedProbeSample):
     16
    1172014-01-15  Gavin Barraclough  <barraclough@apple.com>
    218
  • trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions-expected.txt

    r159520 r162096  
    1818PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object"}]}
    1919PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:2"}
     20PASS: Probe sample payload: {"type":"number","value":12,"description":"12"}
    2021inside breakpointActions a:(100) b:([object HTMLBodyElement])
    2122PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-before","location":"breakpoint.js:19:2"}
    2223PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object","subtype":"node"}]}
    2324PASS: Console Message: {"source":"javascript","level":"log","text":"log-action-after","location":"breakpoint.js:19:2"}
     25PASS: Probe sample payload: {"type":"number","value":100,"description":"100"}
    2426
  • trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions.html

    r155132 r162096  
    77{
    88    InspectorTest.importScript("../../../../inspector-protocol/resources/console-helper.js");
     9    InspectorTest.importScript("../../../../inspector-protocol/resources/probe-helper.js");
    910
    1011    InspectorTest.sendCommand("Console.enable", {});
     
    1415    });
    1516
    16     var expectLogs = false;
    17     var logsSeen = 0;
    18     const expectedLogs = 6;
     17    var isExpectingLogs = false;
     18    var isExpectingSamples = false;
     19    var logCount = 0;
     20    var sampleCount = 0;
     21    const expectedLogCount = 6;
     22    const expectedSampleCount = 2;
     23
     24    function receivedAllExpectedOutput() {
     25        return logCount === expectedLogCount && sampleCount === expectedSampleCount;
     26    }
    1927
    2028    InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
     
    3139                    {"type": "sound"},
    3240                    {"type": "evaluate", "data": "(function() { console.log('eval-action', a, b); })()"},
    33                     {"type": "log", "data": "log-action-after"}
     41                    {"type": "log", "data": "log-action-after"},
     42                    {"type": "probe", "data": "a"}
    3443                ]
    3544            };
     
    4251                InspectorTest.sendCommand("Runtime.evaluate", {expression: "breakpointActions(2, 12)"});
    4352                InspectorTest.sendCommand("Runtime.evaluate", {expression: "breakpointActions(2, {x:1,y:2})"}, function() {
    44                     expectLogs = true;
     53                    isExpectingLogs = true;
     54                    isExpectingSamples = true;
    4555                    InspectorTest.log("Running breakpointActions to triggering the breakpoint actions");
    4656                    InspectorTest.sendCommand("Runtime.evaluate", {expression: "breakpointActions(12, {x:1,y:2})"}, function() {
     
    6070    }
    6171
     72    InspectorTest.eventHandler["Debugger.didSampleProbe"] = function(messageObject)
     73    {
     74        if (!isExpectingSamples) {
     75            InspectorTest.log("FAIL: unexpected probe sample, probe samples should only have come from breakpoint actions.");
     76            InspectorTest.completeTest();
     77            return;
     78        }
     79
     80        var simplifiedSample = ProbeHelper.simplifiedProbeSample(messageObject);
     81        InspectorTest.log("PASS: Probe sample payload: " + JSON.stringify(simplifiedSample.payload));
     82
     83        ++sampleCount;
     84
     85        if (receivedAllExpectedOutput())
     86            InspectorTest.completeTest();
     87    }
     88
    6289    InspectorTest.eventHandler["Console.messageAdded"] = function(messageObject)
    6390    {
    64         if (!expectLogs) {
     91        if (!isExpectingLogs) {
    6592            InspectorTest.log("FAIL: unexpected log, logs should only have come from breakpoint actions.");
    6693            InspectorTest.completeTest();
     
    7198        InspectorTest.log("PASS: Console Message: " + JSON.stringify(simplifiedMessage));
    7299
    73         if (++logsSeen === expectedLogs)
     100        ++logCount;
     101
     102        if (receivedAllExpectedOutput())
    74103            InspectorTest.completeTest();
    75104    }
  • trunk/Source/JavaScriptCore/ChangeLog

    r162017 r162096  
     12014-01-15  Brian Burg  <bburg@apple.com>
     2
     3        Web Inspector: capture probe samples on the backend
     4        https://bugs.webkit.org/show_bug.cgi?id=126668
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Add the 'probe' breakpoint action to the protocol. Change the setBreakpoint
     9        commands to return a list of assigned breakpoint action identifiers
     10        Add a type for breakpoint action identifiers. Add an event for sending
     11        captured probe samples to the inspector frontend.
     12
     13        * inspector/protocol/Debugger.json:
     14
    1152014-01-10  Mark Hahnenberg  <mhahnenberg@apple.com>
    216
  • trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json

    r161691 r162096  
    99        },
    1010        {
     11            "id": "BreakpointActionIdentifier",
     12            "type": "integer",
     13            "description": "Breakpoint action identifier."
     14        },
     15        {
    1116            "id": "ScriptId",
    1217            "type": "string",
     
    3237            "type": "object",
    3338            "properties": [
    34                 { "name": "type", "type": "string", "enum": ["log", "evaluate", "sound"], "description": "Different kinds of breakpoint actions." },
     39                { "name": "type", "type": "string", "enum": ["log", "evaluate", "sound", "probe"], "description": "Different kinds of breakpoint actions." },
    3540                { "name": "data", "type": "string", "optional": true, "description": "Data associated with this breakpoint type (e.g. for type \"eval\" this is the JavaScript string to evalulate)." }
    3641            ],
     
    7984            ],
    8085            "description": "Scope description."
     86        },
     87        {
     88            "id": "ProbeSample",
     89            "description": "A sample collected by evaluating a probe breakpoint action.",
     90            "type": "object",
     91            "properties": [
     92                { "name": "probeId", "$ref": "BreakpointActionIdentifier", "description": "Identifier of the probe breakpoint action that created the sample." },
     93                { "name": "sampleId", "type": "integer", "description": "Unique identifier for this sample." },
     94                { "name": "batchId", "type": "integer", "description": "A batch identifier which is the same for all samples taken at the same breakpoint hit." },
     95                { "name": "timestamp", "type": "number", "description": "Timestamp of when the sample was taken." },
     96                { "name": "payload", "$ref": "Runtime.RemoteObject", "description": "Contents of the sample." }
     97            ]
    8198        }
    8299    ],
     
    108125            "returns": [
    109126                { "name": "breakpointId", "$ref": "BreakpointId", "description": "Id of the created breakpoint for further reference." },
    110                 { "name": "locations", "type": "array", "items": { "$ref": "Location"}, "description": "List of the locations this breakpoint resolved into upon addition." }
     127                { "name": "locations", "type": "array", "items": { "$ref": "Location"}, "description": "List of the locations this breakpoint resolved into upon addition." },
     128                { "name": "breakpointActionIdentifiers", "type": "array", "items": { "$ref": "BreakpointActionIdentifier" }, "description": "Assigned breakpoint action identifiers." }
    111129            ],
    112130            "description": "Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this command is issued, all existing parsed scripts will have breakpoints resolved and returned in <code>locations</code> property. Further matching script parsing will result in subsequent <code>breakpointResolved</code> events issued. This logical breakpoint will survive page reloads."
     
    120138            "returns": [
    121139                { "name": "breakpointId", "$ref": "BreakpointId", "description": "Id of the created breakpoint for further reference." },
    122                 { "name": "actualLocation", "$ref": "Location", "description": "Location this breakpoint resolved into." }
     140                { "name": "actualLocation", "$ref": "Location", "description": "Location this breakpoint resolved into." },
     141                { "name": "breakpointActionIdentifiers", "type": "array", "items": { "$ref": "BreakpointActionIdentifier" }, "description": "Assigned breakpoint action identifiers." }
    123142            ],
    124143            "description": "Sets JavaScript breakpoint at a given location."
     
    274293            "name": "resumed",
    275294            "description": "Fired when the virtual machine resumed execution."
     295        },
     296        {
     297            "name": "didSampleProbe",
     298            "description": "Fires when a new proben sample is collected.",
     299            "parameters": [
     300                { "name": "sample", "$ref": "ProbeSample", "description": "A collected probe sample." }
     301            ]
    276302        }
    277303    ]
  • trunk/Source/WebCore/ChangeLog

    r162085 r162096  
     12014-01-15  Brian Burg  <bburg@apple.com>
     2
     3        Web Inspector: capture probe samples on the backend
     4        https://bugs.webkit.org/show_bug.cgi?id=126668
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Test: inspector-protocol/debugger/setProbe-multiple-actions.html
     9
     10        Add the probe breakpoint action type. A probe action
     11        evaluates an expression on the script call frame, and
     12        the result is aggregated on a per-probe basis. Each
     13        evaluated expression result is called a probe sample.
     14
     15        * bindings/js/ScriptDebugServer.cpp:
     16        (WebCore::ScriptDebugServer::evaluateBreakpointAction): Teach
     17        the debug server to evaluate a probe.
     18
     19        (WebCore::ScriptDebugServer::dispatchDidSampleProbe): Added.
     20        (WebCore::ScriptDebugServer::handleBreakpointHit): Increment a hit count.
     21        (WebCore::ScriptDebugServer::getActionsForBreakpoint):
     22        * bindings/js/ScriptDebugServer.h:
     23        * inspector/InspectorDebuggerAgent.cpp:
     24        (WebCore::objectGroupForBreakpointAction): Added. Create an object
     25        group for each breakpoint action. Currently only probes make objects.
     26        (WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent):
     27        (WebCore::InspectorDebuggerAgent::disable):
     28        (WebCore::InspectorDebuggerAgent::enable): Remove stale comment.
     29        (WebCore::breakpointActionTypeForString): Add new case.
     30        (WebCore::InspectorDebuggerAgent::breakpointActionsFromProtocol): Make
     31        this a member function instead of a static function, so it can increment
     32        the breakpoint action identifier counter.
     33        (WebCore::InspectorDebuggerAgent::setBreakpointByUrl): Propagate the
     34        assigned breakpoint action identifiers.
     35        (WebCore::InspectorDebuggerAgent::setBreakpoint): Propagate the
     36        assigned breakpoint action identifiers.
     37        (WebCore::InspectorDebuggerAgent::removeBreakpoint): Release object
     38        groups for any actions that were associated with the removed breakpoint.
     39        (WebCore::InspectorDebuggerAgent::didSampleProbe): Added.
     40        (WebCore::InspectorDebuggerAgent::clearResolvedBreakpointState): Renamed from clear().
     41        (WebCore::InspectorDebuggerAgent::didClearGlobalObject): Renamed from reset().
     42        * inspector/InspectorDebuggerAgent.h:
     43        * inspector/PageDebuggerAgent.cpp:
     44        (WebCore::PageDebuggerAgent::didClearMainFrameWindowObject):
     45        * inspector/ScriptBreakpoint.h:
     46        (WebCore::ScriptBreakpointAction::ScriptBreakpointAction): Add identifier member.
     47        * inspector/ScriptDebugListener.h:
     48
    1492014-01-15  Brent Fulgham  <bfulgham@apple.com>
    250
  • trunk/Source/WebCore/bindings/js/ScriptDebugServer.cpp

    r161771 r162096  
    11/*
    2  * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
    33 * Copyright (C) 2010-2011 Google Inc. All rights reserved.
     4 * Copyright (C) 2013 University of Washington. All rights reserved.
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    4546#include <runtime/JSLock.h>
    4647#include <wtf/MainThread.h>
     48#include <wtf/NeverDestroyed.h>
     49#include <wtf/TemporaryChange.h>
    4750#include <wtf/text/WTFString.h>
    4851
     
    9194}
    9295
    93 bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& breakpointAction) const
     96bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& breakpointAction)
    9497{
    9598    DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame();
     
    111114        systemBeep();
    112115        break;
     116    case ScriptBreakpointActionTypeProbe: {
     117        JSValue exception;
     118        JSValue result = debuggerCallFrame->evaluate(breakpointAction.data, exception);
     119        if (exception)
     120            reportException(debuggerCallFrame->exec(), exception);
     121
     122        JSC::ExecState* state = debuggerCallFrame->scope()->globalObject()->globalExec();
     123        Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception : result);
     124        dispatchDidSampleProbe(state, breakpointAction.identifier, wrappedResult);
     125        break;
     126    }
    113127    }
    114128
     
    141155}
    142156
     157void ScriptDebugServer::dispatchDidSampleProbe(ExecState* exec, int identifier, const Deprecated::ScriptValue& sample)
     158{
     159    if (m_callingListeners)
     160        return;
     161
     162    ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject());
     163    if (!listeners)
     164        return;
     165    ASSERT(!listeners->isEmpty());
     166
     167    TemporaryChange<bool> change(m_callingListeners, true);
     168
     169    Vector<ScriptDebugListener*> listenersCopy;
     170    copyToVector(*listeners, listenersCopy);
     171    for (auto listener : listenersCopy)
     172        listener->didSampleProbe(exec, identifier, m_hitCount, sample);
     173}
     174
    143175void ScriptDebugServer::dispatchDidContinue(ScriptDebugListener* listener)
    144176{
     
    252284void ScriptDebugServer::handleBreakpointHit(const JSC::Breakpoint& breakpoint)
    253285{
     286    m_hitCount++;
    254287    BreakpointIDToActionsMap::iterator it = m_breakpointIDToActions.find(breakpoint.id);
    255288    if (it != m_breakpointIDToActions.end()) {
     
    291324}
    292325
     326const Vector<ScriptBreakpointAction>& ScriptDebugServer::getActionsForBreakpoint(JSC::BreakpointID breakpointID)
     327{
     328    ASSERT(breakpointID != JSC::noBreakpointID);
     329
     330    if (m_breakpointIDToActions.contains(breakpointID))
     331        return m_breakpointIDToActions.find(breakpointID)->value;
     332   
     333    static NeverDestroyed<Vector<ScriptBreakpointAction>> emptyActionVector = Vector<ScriptBreakpointAction>();
     334    return emptyActionVector;
     335}
     336
    293337} // namespace WebCore
    294338
  • trunk/Source/WebCore/bindings/js/ScriptDebugServer.h

    r161771 r162096  
    6363    virtual void recompileAllJSFunctions() = 0;
    6464
     65    const Vector<ScriptBreakpointAction>& getActionsForBreakpoint(JSC::BreakpointID);
     66
    6567    class Task {
    6668        WTF_MAKE_FAST_ALLOCATED;
     
    8587    virtual bool isContentScript(JSC::ExecState*);
    8688
    87     bool evaluateBreakpointAction(const ScriptBreakpointAction&) const;
     89    bool evaluateBreakpointAction(const ScriptBreakpointAction&);
    8890
    8991    void dispatchFunctionToListeners(JavaScriptExecutionCallback, JSC::JSGlobalObject*);
     
    9395    void dispatchDidParseSource(const ListenerSet& listeners, JSC::SourceProvider*, bool isContentScript);
    9496    void dispatchFailedToParseSource(const ListenerSet& listeners, JSC::SourceProvider*, int errorLine, const String& errorMessage);
     97    void dispatchDidSampleProbe(JSC::ExecState*, int probeIdentifier, const Deprecated::ScriptValue& sample);
    9598
    9699    bool m_doneProcessingDebuggerEvents;
     
    109112    void recompileAllJSFunctionsTimerFired(Timer<ScriptDebugServer>&);
    110113
     114    unsigned m_hitCount;
    111115    bool m_callingListeners;
    112116    BreakpointIDToActionsMap m_breakpointIDToActions;
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp

    r161761 r162096  
    5757const char* InspectorDebuggerAgent::backtraceObjectGroup = "backtrace";
    5858
     59static String objectGroupForBreakpointAction(int identifier)
     60{
     61    DEFINE_STATIC_LOCAL(const AtomicString, objectGroup, ("breakpoint-action-", AtomicString::ConstructFromLiteral));
     62    return makeString(objectGroup, String::number(identifier));
     63}
     64
    5965InspectorDebuggerAgent::InspectorDebuggerAgent(InstrumentingAgents* instrumentingAgents, InjectedScriptManager* injectedScriptManager)
    6066    : InspectorAgentBase(ASCIILiteral("Debugger"), instrumentingAgents)
    6167    , m_injectedScriptManager(injectedScriptManager)
    62     , m_pausedScriptState(0)
     68    , m_pausedScriptState(nullptr)
    6369    , m_continueToLocationBreakpointID(JSC::noBreakpointID)
    6470    , m_enabled(false)
    6571    , m_javaScriptPauseScheduled(false)
    66     , m_listener(0)
     72    , m_listener(nullptr)
     73    , m_nextProbeSampleId(1)
     74    , m_nextBreakpointActionIdentifier(1)
    6775{
    6876    // FIXME: make breakReason optional so that there was no need to init it with "other".
     
    7987    m_instrumentingAgents->setInspectorDebuggerAgent(this);
    8088
    81     // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends
    8289    scriptDebugServer().setBreakpointsActivated(true);
    8390    startListeningScriptDebugServer();
     
    9299{
    93100    m_javaScriptBreakpoints.clear();
    94     m_instrumentingAgents->setInspectorDebuggerAgent(0);
     101    m_instrumentingAgents->setInspectorDebuggerAgent(nullptr);
    95102
    96103    stopListeningScriptDebugServer();
    97     scriptDebugServer().clearBreakpoints();
    98     scriptDebugServer().continueProgram();
    99     clear();
     104    clearResolvedBreakpointState();
    100105
    101106    if (m_listener)
     
    194199        return true;
    195200    }
     201    if (typeString == Inspector::TypeBuilder::getJSEnumConstantValue(Inspector::TypeBuilder::Debugger::BreakpointAction::Type::Probe)) {
     202        *output = ScriptBreakpointActionTypeProbe;
     203        return true;
     204    }
    196205
    197206    return false;
    198207}
    199208
    200 static bool breakpointActionsFromProtocol(ErrorString* errorString, RefPtr<InspectorArray>& actions, Vector<ScriptBreakpointAction>* result)
     209bool InspectorDebuggerAgent::breakpointActionsFromProtocol(ErrorString* errorString, RefPtr<InspectorArray>& actions, Vector<ScriptBreakpointAction>* result)
    201210{
    202211    if (!actions)
     
    231240        object->getString("data", &data);
    232241
    233         result->append(ScriptBreakpointAction(type, data));
     242        result->append(ScriptBreakpointAction(type, m_nextBreakpointActionIdentifier++, data));
    234243    }
    235244
     
    237246}
    238247
    239 void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations)
     248void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>>& breakpointActionIdentifiers)
    240249{
    241250    locations = Array<Inspector::TypeBuilder::Debugger::Location>::create();
     
    268277        return;
    269278
     279    breakpointActionIdentifiers = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>::create();
     280    for (ScriptBreakpointAction& action : breakpointActions)
     281        breakpointActionIdentifiers->addItem(action.identifier);
     282
    270283    m_javaScriptBreakpoints.set(breakpointIdentifier, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, actions, isRegex, autoContinue));
    271284
     
    298311}
    299312
    300 void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<InspectorObject>& location, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation)
     313void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<InspectorObject>& location, const RefPtr<InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId* outBreakpointIdentifier, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>>& breakpointActionIdentifiers)
    301314{
    302315    JSC::SourceID sourceID;
     
    319332    if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions))
    320333        return;
     334   
     335    breakpointActionIdentifiers = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>::create();
     336    for (ScriptBreakpointAction& action : breakpointActions)
     337        breakpointActionIdentifiers->addItem(action.identifier);
    321338
    322339    String breakpointIdentifier = String::number(sourceID) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
     
    338355    m_javaScriptBreakpoints.remove(breakpointIdentifier);
    339356
    340     BreakpointIdentifierToDebugServerBreakpointIDsMap::iterator debugServerBreakpointIDsIterator = m_breakpointIdentifierToDebugServerBreakpointIDs.find(breakpointIdentifier);
    341     if (debugServerBreakpointIDsIterator == m_breakpointIdentifierToDebugServerBreakpointIDs.end())
    342         return;
    343     for (size_t i = 0; i < debugServerBreakpointIDsIterator->value.size(); ++i)
    344         scriptDebugServer().removeBreakpoint(debugServerBreakpointIDsIterator->value[i]);
    345     m_breakpointIdentifierToDebugServerBreakpointIDs.remove(debugServerBreakpointIDsIterator);
     357    Vector<JSC::BreakpointID> breakpointIDs = m_breakpointIdentifierToDebugServerBreakpointIDs.take(breakpointIdentifier);
     358    for (auto breakpointID : breakpointIDs) {
     359        const Vector<ScriptBreakpointAction>& breakpointActions = scriptDebugServer().getActionsForBreakpoint(breakpointID);
     360        for (auto& action : breakpointActions)
     361            m_injectedScriptManager->releaseObjectGroup(objectGroupForBreakpointAction(action.identifier));
     362
     363        scriptDebugServer().removeBreakpoint(breakpointID);
     364    }
    346365}
    347366
     
    654673}
    655674
     675void InspectorDebuggerAgent::didSampleProbe(JSC::ExecState* scriptState, int probeIdentifier, int hitCount, const Deprecated::ScriptValue& sample)
     676{
     677    int sampleId = m_nextProbeSampleId++;
     678
     679    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
     680    RefPtr<TypeBuilder::Runtime::RemoteObject> payload = injectedScript.wrapObject(sample, objectGroupForBreakpointAction(probeIdentifier));
     681    RefPtr<TypeBuilder::Debugger::ProbeSample> result = TypeBuilder::Debugger::ProbeSample::create()
     682        .setProbeId(probeIdentifier)
     683        .setSampleId(sampleId)
     684        .setBatchId(hitCount)
     685        .setTimestamp(monotonicallyIncreasingTime())
     686        .setPayload(payload.release());
     687
     688    m_frontendDispatcher->didSampleProbe(result.release());
     689}
     690
    656691void InspectorDebuggerAgent::didContinue()
    657692{
     
    669704}
    670705
    671 void InspectorDebuggerAgent::clear()
    672 {
    673     m_pausedScriptState = 0;
     706void InspectorDebuggerAgent::clearResolvedBreakpointState()
     707{
     708    ErrorString dummyError;
     709    Vector<String> breakpointIdentifiers;
     710    copyKeysToVector(m_breakpointIdentifierToDebugServerBreakpointIDs, breakpointIdentifiers);
     711    for (const String& identifier : breakpointIdentifiers)
     712        removeBreakpoint(&dummyError, identifier);
     713
     714    scriptDebugServer().continueProgram();
     715
     716    m_pausedScriptState = nullptr;
    674717    m_currentCallStack = Deprecated::ScriptValue();
    675718    m_scripts.clear();
     
    678721    clearBreakDetails();
    679722    m_javaScriptPauseScheduled = false;
    680     ErrorString error;
    681     setOverlayMessage(&error, 0);
     723    setOverlayMessage(&dummyError, nullptr);
    682724}
    683725
     
    697739}
    698740
    699 void InspectorDebuggerAgent::reset()
    700 {
    701     scriptDebugServer().clearBreakpoints();
    702     m_scripts.clear();
    703     m_breakpointIdentifierToDebugServerBreakpointIDs.clear();
     741void InspectorDebuggerAgent::didClearGlobalObject()
     742{
    704743    if (m_frontendDispatcher)
    705744        m_frontendDispatcher->globalObjectCleared();
     745
     746    clearResolvedBreakpointState();
    706747}
    707748
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.h

    r161761 r162096  
    8282    virtual void setBreakpointsActive(ErrorString*, bool active);
    8383
    84     virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations);
    85     virtual void setBreakpoint(ErrorString*, const RefPtr<Inspector::InspectorObject>& location, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation);
     84    virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location>>& locations, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>>& breakpointActionIdentifiers);
     85    virtual void setBreakpoint(ErrorString*, const RefPtr<Inspector::InspectorObject>& location, const RefPtr<Inspector::InspectorObject>* options, Inspector::TypeBuilder::Debugger::BreakpointId*, RefPtr<Inspector::TypeBuilder::Debugger::Location>& actualLocation, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier>>& breakpointActionIdentifiers);
    8686    virtual void removeBreakpoint(ErrorString*, const String& breakpointIdentifier);
    8787    virtual void continueToLocation(ErrorString*, const RefPtr<Inspector::InspectorObject>& location);
     
    139139    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exception);
    140140    virtual void didContinue();
    141     void reset();
     141    void didClearGlobalObject();
    142142
    143143private:
     
    146146    virtual void didParseSource(JSC::SourceID, const Script&) OVERRIDE FINAL;
    147147    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) OVERRIDE FINAL;
     148    virtual void didSampleProbe(JSC::ExecState*, int probeIdentifier, int hitCount, const Deprecated::ScriptValue& sample) OVERRIDE FINAL;
    148149
    149150    PassRefPtr<Inspector::TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointIdentifier, JSC::SourceID, const ScriptBreakpoint&);
    150     void clear();
    151151    bool assertPaused(ErrorString*);
     152    void clearResolvedBreakpointState();
    152153    void clearBreakDetails();
     154
     155    bool breakpointActionsFromProtocol(ErrorString*, RefPtr<Inspector::InspectorArray>& actions, Vector<ScriptBreakpointAction>* result);
    153156
    154157    String sourceMapURLForScript(const Script&);
     
    172175    bool m_javaScriptPauseScheduled;
    173176    Listener* m_listener;
     177    int m_nextProbeSampleId;
     178    int m_nextBreakpointActionIdentifier;
    174179};
    175180
  • trunk/Source/WebCore/inspector/PageDebuggerAgent.cpp

    r161784 r162096  
    116116void PageDebuggerAgent::didClearMainFrameWindowObject()
    117117{
    118     reset();
     118    didClearGlobalObject();
    119119}
    120120
  • trunk/Source/WebCore/inspector/ScriptBreakpoint.h

    r155132 r162096  
    3939    ScriptBreakpointActionTypeLog,
    4040    ScriptBreakpointActionTypeEvaluate,
    41     ScriptBreakpointActionTypeSound
     41    ScriptBreakpointActionTypeSound,
     42    ScriptBreakpointActionTypeProbe
    4243} ScriptBreakpointActionType;
    4344
    4445struct ScriptBreakpointAction {
    45     ScriptBreakpointAction(ScriptBreakpointActionType type, const String& data)
     46    ScriptBreakpointAction(ScriptBreakpointActionType type, int identifier, const String& data)
    4647        : type(type)
     48        , identifier(identifier)
    4749        , data(data)
    4850    {
     
    5052
    5153    ScriptBreakpointActionType type;
     54    int identifier;
    5255    String data;
    5356};
  • trunk/Source/WebCore/inspector/ScriptDebugListener.h

    r160682 r162096  
    7272    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
    7373    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue& callFrames, const Deprecated::ScriptValue& exception) = 0;
     74    virtual void didSampleProbe(JSC::ExecState*, int probeIdentifier, int hitCount, const Deprecated::ScriptValue& result) = 0;
    7475    virtual void didContinue() = 0;
    7576};
  • trunk/Source/WebInspectorUI/ChangeLog

    r162084 r162096  
     12014-01-15  Brian Burg  <bburg@apple.com>
     2
     3        Web Inspector: capture probe samples on the backend
     4        https://bugs.webkit.org/show_bug.cgi?id=126668
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        * UserInterface/InspectorJSBackendCommands.js: Add probe enumeration value.
     9
    1102014-01-15  Andreas Kling  <akling@apple.com>
    211
  • trunk/Source/WebInspectorUI/UserInterface/InspectorJSBackendCommands.js

    r161691 r162096  
    99// Debugger.
    1010InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
    11 InspectorBackend.registerEnum("Debugger.BreakpointActionType", {Log: "log", Evaluate: "evaluate", Sound: "sound"});
     11InspectorBackend.registerEnum("Debugger.BreakpointActionType", {Log: "log", Evaluate: "evaluate", Sound: "sound", Probe: "probe"});
    1212InspectorBackend.registerEnum("Debugger.ScopeType", {Global: "global", Local: "local", With: "with", Closure: "closure", Catch: "catch"});
    1313InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
     
    1717InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
    1818InspectorBackend.registerEvent("Debugger.resumed", []);
     19InspectorBackend.registerEvent("Debugger.didSampleProbe", ["sample"]);
    1920InspectorBackend.registerCommand("Debugger.enable", [], []);
    2021InspectorBackend.registerCommand("Debugger.disable", [], []);
Note: See TracChangeset for help on using the changeset viewer.