Ignore:
Timestamp:
Sep 3, 2020, 10:53:21 AM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: allow special JavaScript breakpoints to be configured
https://bugs.webkit.org/show_bug.cgi?id=215794

Reviewed by Brian Burg.

Source/JavaScriptCore:

  • inspector/protocol/Debugger.json:

Add an options parameter to the following commands for configuring the related breakpoint:

  • Debugger.setPauseOnDebuggerStatements
  • Debugger.setPauseOnExceptions
  • Debugger.setPauseOnAssertions
  • Debugger.setPauseOnMicrotasks
  • debugger/Debugger.h:

(JSC::Debugger::needsExceptionCallbacks const):
(JSC::Debugger::pauseOnAllExceptionsBreakpoint const): Added.
(JSC::Debugger::setPauseOnAllExceptionsBreakpoint): Added.
(JSC::Debugger::pauseOnUncaughtExceptionsBreakpoint const): Added.
(JSC::Debugger::setPauseOnUncaughtExceptionsBreakpoint): Added.
(JSC::Debugger::setPauseOnDebuggerStatementsBreakpoint): Added.
(JSC::Debugger::pauseOnExceptionsState const): Deleted.
(JSC::Debugger::setPauseOnDebuggerStatements): Deleted.

  • debugger/Debugger.cpp:

(JSC::Debugger::TemporarilyDisableExceptionBreakpoints::TemporarilyDisableExceptionBreakpoints): Added.
(JSC::Debugger::TemporarilyDisableExceptionBreakpoints::~TemporarilyDisableExceptionBreakpoints): Added.
(JSC::Debugger::TemporarilyDisableExceptionBreakpoints::replace): Added.
(JSC::Debugger::TemporarilyDisableExceptionBreakpoints::restore): Added.
(JSC::Debugger::Debugger):
(JSC::Debugger::breakProgram):
(JSC::Debugger::exception):
(JSC::Debugger::didReachDebuggerStatement):
(JSC::Debugger::setPauseOnExceptionsState): Deleted.
Add JSC::Breakpoint member variables for the Debugger Statements and Exceptions
breakpoints. Split the Exceptions breakpoint into two JSC::Breakpoint now that
All Exceptions and Uncaught Exceptions can be independently configured (the All
Exceptions breakpoint still takes precedence).

  • debugger/DebuggerCallFrame.h:
  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
If there is no CallFrame, climb the backtrace until the first valid CallFrame is reached.
This is needed when pausing in native code, such as for assertions/exceptions.

  • debugger/Breakpoint.h:

Export JSC::Breakpoint::create so that other parts of WebKit can create breakpoints.

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

(Inspector::InspectorDebuggerAgent::disable):
(Inspector::InspectorDebuggerAgent::handleConsoleAssert):
(Inspector::InspectorDebuggerAgent::setPauseOnDebuggerStatements):
(Inspector::InspectorDebuggerAgent::setPauseOnExceptions):
(Inspector::InspectorDebuggerAgent::setPauseOnAssertions):
(Inspector::InspectorDebuggerAgent::setPauseOnMicrotasks):
(Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
(Inspector::InspectorDebuggerAgent::scriptExecutionBlockedByCSP):
(Inspector::InspectorDebuggerAgent::willRunMicrotask):
(Inspector::InspectorDebuggerAgent::didRunMicrotask):
(Inspector::InspectorDebuggerAgent::breakProgram):
Add JSC::Breakpoint member variables for the Assertion Failures and All Microtasks
breakpoints. Pass them to the JSC::Debugger when they are hit.

  • inspector/agents/InspectorAuditAgent.cpp:

(Inspector::InspectorAuditAgent::run):

  • inspector/agents/InspectorRuntimeAgent.cpp:

(Inspector::InspectorRuntimeAgent::evaluate):
(Inspector::InspectorRuntimeAgent::callFunctionOn):
(Inspector::InspectorRuntimeAgent::getPreview):
(Inspector::InspectorRuntimeAgent::getProperties):
(Inspector::InspectorRuntimeAgent::getDisplayableProperties):
(Inspector::setPauseOnExceptionsState): Deleted.
Use TemporarilyDisableExceptionBreakpoints to save, override, and restore the exceptions
breakpoints now that they've been separated into two JSC::Breakpoint instead of an enum.

Source/WebInspectorUI:

  • UserInterface/Models/Breakpoint.js:

(WI.Breakpoint.prototype.reset): Added.
Provide a way to consistently clear the current configuration.

  • UserInterface/Models/JavaScriptBreakpoint.js:

(WI.JavaScriptBreakpoint.supportsMicrotasks): Added.
(WI.JavaScriptBreakpoint.supportsDebuggerStatements): Added.
(WI.JavaScriptBreakpoint.fromJSON):
(WI.JavaScriptBreakpoint.prototype.toJSON):
(WI.JavaScriptBreakpoint.prototype.get editable):
(WI.JavaScriptBreakpoint.prototype._isSpecial):

  • UserInterface/Models/SourceCodeLocation.js:

(WI.SourceCodeLocation.get specialBreakpointLocation): Added.
Add a helper for the special null:Infinity:Infinity breakpoint location for consistency.

  • UserInterface/Controllers/DebuggerManager.js:

(WI.DebuggerManager):
(WI.DebuggerManager.prototype.async initializeTarget):
(WI.DebuggerManager.prototype.createAssertionFailuresBreakpoint): Added.
(WI.DebuggerManager.prototype.createAllMicrotasksBreakpoint): Added.
(WI.DebuggerManager.prototype.set breakpointsEnabled):
(WI.DebuggerManager.prototype.addBreakpoint):
(WI.DebuggerManager.prototype.removeBreakpoint):
(WI.DebuggerManager.prototype._setPauseOnExceptions): Added.
(WI.DebuggerManager.prototype._createSpecialBreakpoint): Added.
(WI.DebuggerManager.prototype._updateSpecialBreakpoint): Added.
(WI.DebuggerManager.prototype._breakpointDisabledStateDidChange):
(WI.DebuggerManager.prototype._breakpointEditablePropertyDidChange):
(WI.DebuggerManager.prototype._updateBreakOnExceptionsState): Deleted.
Maintain a WI.Setting for the configuration of each special WI.JavaScriptBreakpoint.
Have a common path for updating all special WI.JavaScriptBreakpoint to avoid duplicated
code.
Add methods for creating the Assertion Failures and All Microtasks WI.JavaScriptBreakpoint
since they can be removed (in addition to being disabled) and re-added.

  • UserInterface/Views/BreakpointPopover.js:

(WI.BreakpointPopover.appendContextMenuItems):

  • UserInterface/Views/BreakpointTreeElement.js:

(WI.BreakpointTreeElement.prototype.ondelete):
If the WI.Breakpoint is not removable, make sure to reset it in addition to disabling
it so that no configuration persists if the WI.Breakpoint is later enabled.

  • UserInterface/Views/SourcesNavigationSidebarPanel.js:

(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype._handleBreakpointTreeOutlineElementRemoved): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleBreakpointElementAddedOrRemoved): Deleted.
Eliminate the need to listen for when breakpoints are added to the WI.TreeOutline, which
was previously used to update the WI.Setting for whether special WI.JavaScriptBreakpoint
are visible.
Don't assume that a WI.Breakpoint exists for each special WI.JavaScriptBreakpoint.

  • UserInterface/Base/Setting.js:

(WI.Setting):
(WI.Setting.migrateValue):
(WI.Setting.reset):
(WI.Setting.prototype.get value):
(WI.Setting.prototype.save):
(WI.Setting._localStorageKeyPrefix): Added.
(WI.Setting._localStorageKey): Deleted.
Eagerly compute the key prefix as it shouldn't change through the lifetime of Web Inspector
and is used early on too.
Add a static member isFirstLaunch which can be used by other WI.Setting to adjust their
value when Web Inspector is in a clean state (e.g. show the Assertion Failures breakpoint by
default, but only for the first launch). This is needed because WI.Setting clears the key
from localStorage if the current value matches the _defaultValue.

  • UserInterface/Models/ProbeSet.js:

(WI.ProbeSet):
(WI.ProbeSet.prototype.willRemove):
(WI.ProbeSet.prototype._sampleCollected):
(WI.ProbeSet.prototype._breakpointResolvedStateDidChange): Deleted.
Drive-by: remove an unused event.

  • Localizations/en.lproj/localizedStrings.js:

Source/WebKitLegacy/mac:

  • WebView/WebScriptDebugger.mm:

(WebScriptDebugger::WebScriptDebugger):

LayoutTests:

  • inspector/debugger/resources/breakpoint-options-utilities.js: Added.

(TestPage.registerInitializer.InspectorTest.BreakpointOptions.addTestCases):
(TestPage.registerInitializer.InspectorTest.BreakpointOptions.addTestCases.removeBreakpoint):

  • inspector/debugger/break-on-exception.html:
  • inspector/debugger/break-on-exception-expected.txt:
  • inspector/debugger/break-on-uncaught-exception.html:
  • inspector/debugger/break-on-uncaught-exception-expected.txt:
  • inspector/debugger/setPauseOnAssertions.html:
  • inspector/debugger/setPauseOnAssertions-expected.txt:
  • inspector/debugger/setPauseOnDebuggerStatements.html:
  • inspector/debugger/setPauseOnDebuggerStatements-expected.txt:
  • inspector/debugger/setPauseOnMicrotasks.html:
  • inspector/debugger/setPauseOnMicrotasks-expected.txt:

Add tests for global JavaScript breakpoint configuration options.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/debugger/Debugger.h

    r266074 r266534  
    4747    VM& vm() { return m_vm; }
    4848
    49     bool needsExceptionCallbacks() const { return m_breakpointsActivated && m_pauseOnExceptionsState != DontPauseOnExceptions; }
     49    bool needsExceptionCallbacks() const { return m_breakpointsActivated && (m_pauseOnAllExceptionsBreakpoint || m_pauseOnUncaughtExceptionsBreakpoint); }
    5050    bool isInteractivelyDebugging() const { return m_breakpointsActivated; }
    5151
     
    7171    void evaluateBreakpointActions(Breakpoint&, JSGlobalObject*);
    7272
    73     enum PauseOnExceptionsState {
    74         DontPauseOnExceptions,
    75         PauseOnAllExceptions,
    76         PauseOnUncaughtExceptions
    77     };
    78     PauseOnExceptionsState pauseOnExceptionsState() const { return m_pauseOnExceptionsState; }
    79     JS_EXPORT_PRIVATE void setPauseOnExceptionsState(PauseOnExceptionsState);
    80 
    81     void setPauseOnDebuggerStatements(bool enabled) { m_pauseOnDebuggerStatements = enabled; }
     73    void setPauseOnDebuggerStatementsBreakpoint(RefPtr<Breakpoint>&& breakpoint) { m_pauseOnDebuggerStatementsBreakpoint = WTFMove(breakpoint); }
     74
     75    class TemporarilyDisableExceptionBreakpoints {
     76    public:
     77        TemporarilyDisableExceptionBreakpoints(Debugger&);
     78        ~TemporarilyDisableExceptionBreakpoints();
     79
     80        void replace();
     81        void restore();
     82
     83    private:
     84        Debugger& m_debugger;
     85        RefPtr<Breakpoint> m_pauseOnAllExceptionsBreakpoint;
     86        RefPtr<Breakpoint> m_pauseOnUncaughtExceptionsBreakpoint;
     87    };
     88    void setPauseOnAllExceptionsBreakpoint(RefPtr<Breakpoint>&& breakpoint) { m_pauseOnAllExceptionsBreakpoint = WTFMove(breakpoint); }
     89    void setPauseOnUncaughtExceptionsBreakpoint(RefPtr<Breakpoint>&& breakpoint) { m_pauseOnUncaughtExceptionsBreakpoint = WTFMove(breakpoint); }
    8290
    8391    enum ReasonForPause {
     
    99107    bool schedulePauseForSpecialBreakpoint(Breakpoint&);
    100108    bool cancelPauseForSpecialBreakpoint(Breakpoint&);
    101     void breakProgram();
     109    void breakProgram(RefPtr<Breakpoint>&& specialBreakpoint = nullptr);
    102110    void continueProgram();
    103111    void stepNextExpression();
     
    282290    HashMap<SourceID, BlackboxType, WTF::IntHash<SourceID>, WTF::UnsignedWithZeroKeyHashTraits<SourceID>> m_blackboxedScripts;
    283291
    284     PauseOnExceptionsState m_pauseOnExceptionsState;
    285     bool m_pauseOnDebuggerStatements : 1;
    286292    bool m_pauseAtNextOpportunity : 1;
    287293    bool m_pauseOnStepNext : 1;
     
    308314    BreakpointID m_pausingBreakpointID;
    309315
     316    RefPtr<Breakpoint> m_pauseOnAllExceptionsBreakpoint;
     317    RefPtr<Breakpoint> m_pauseOnUncaughtExceptionsBreakpoint;
     318    RefPtr<Breakpoint> m_pauseOnDebuggerStatementsBreakpoint;
     319
    310320    unsigned m_nextProbeSampleId { 1 };
    311321    unsigned m_currentProbeBatchId { 0 };
Note: See TracChangeset for help on using the changeset viewer.