Changeset 288266 in webkit


Ignore:
Timestamp:
Jan 19, 2022 6:45:17 PM (6 months ago)
Author:
Devin Rousso
Message:

Web Inspector: fully blackboxed stack traces don't show the right top call frame
https://bugs.webkit.org/show_bug.cgi?id=235381

Reviewed by Patrick Angle.

Source/WebInspectorUI:

  • UserInterface/Models/StackTrace.js:

(WI.StackTrace):
(WI.StackTrace.fromPayload):
(WI.StackTrace.prototype.get firstNonNativeNonAnonymousNotBlackboxedCallFrame):
Only assign to firstNonNativeNonAnonymousCallFrame once.
Drive-by: Don't re-fetch the blackbox data for the WI.SourceCode of the WI.CallFrame.
Drive-by: Combine optional parameters into an options = {} for current code cleanliness

and greater flexibility for future changes.

  • UserInterface/Models/CallFrame.js:

(WI.CallFrame):
(WI.CallFrame.fromDebuggerPayload):
(WI.CallFrame.fromPayload):

  • UserInterface/Views/ThreadTreeElement.js:

(WI.ThreadTreeElement.prototype.refresh):
Drive-by: Combine optional parameters into an options = {} for current code cleanliness

and greater flexibility for future changes.

  • UserInterface/Views/CallFrameTreeElement.js:

(WI.CallFrameTreeElement):
(WI.CallFrameTreeElement.prototype.onattach):

  • UserInterface/Views/CallFrameView.js:

(WI.CallFrameView):
Drive-by: Don't re-fetch the blackbox data for the WI.SourceCode of the WI.CallFrame.

LayoutTests:

  • inspector/model/stack-trace.html:
  • inspector/model/stack-trace-expected.txt:
  • inspector/debugger/resources/async-stack-trace-test.js:

(TestPage.registerInitializer.window.getAsyncStackTrace):

  • inspector/debugger/resources/log-active-stack-trace.js:

(TestPage.registerInitializer.window.getActiveStackTrace):

  • inspector/debugger/tail-deleted-frames/resources/stack-trace-utilities.js:

(TestPage.registerInitializer.window.getAsyncStackTrace):
Drive-by: Adopt new WI.StackTrace constructor arguments format.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r288264 r288266  
     12022-01-19  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: fully blackboxed stack traces don't show the right top call frame
     4        https://bugs.webkit.org/show_bug.cgi?id=235381
     5
     6        Reviewed by Patrick Angle.
     7
     8        * inspector/model/stack-trace.html:
     9        * inspector/model/stack-trace-expected.txt:
     10
     11        * inspector/debugger/resources/async-stack-trace-test.js:
     12        (TestPage.registerInitializer.window.getAsyncStackTrace):
     13        * inspector/debugger/resources/log-active-stack-trace.js:
     14        (TestPage.registerInitializer.window.getActiveStackTrace):
     15        * inspector/debugger/tail-deleted-frames/resources/stack-trace-utilities.js:
     16        (TestPage.registerInitializer.window.getAsyncStackTrace):
     17        Drive-by: Adopt new `WI.StackTrace` constructor arguments format.
     18
    1192022-01-19  Chris Dumez  <cdumez@apple.com>
    220
  • trunk/LayoutTests/inspector/debugger/resources/async-stack-trace-test.js

    r234635 r288266  
    1010            return null;
    1111
    12         const topCallFrameIsBoundary = false;
    13         const truncated = false;
    14         return new WI.StackTrace(targetData.callFrames, topCallFrameIsBoundary, truncated, targetData.asyncStackTrace);
     12        return new WI.StackTrace(targetData.callFrames, {parentStackTrace: targetData.asyncStackTrace});
    1513    };
    1614
  • trunk/LayoutTests/inspector/debugger/resources/log-active-stack-trace.js

    r249305 r288266  
    5757            return null;
    5858
    59         const topCallFrameIsBoundary = false;
    60         const truncated = false;
    61         return new WI.StackTrace(targetData.callFrames, topCallFrameIsBoundary, truncated, targetData.asyncStackTrace);
     59        return new WI.StackTrace(targetData.callFrames, {parentStackTrace: targetData.asyncStackTrace});
    6260    }
    6361
  • trunk/LayoutTests/inspector/debugger/tail-deleted-frames/resources/stack-trace-utilities.js

    r249586 r288266  
    1010            return null;
    1111
    12         const topCallFrameIsBoundary = false;
    13         const truncated = false;
    14         return new WI.StackTrace(targetData.callFrames, topCallFrameIsBoundary, truncated, targetData.asyncStackTrace);
     12        return new WI.StackTrace(targetData.callFrames, {parentStackTrace: targetData.asyncStackTrace});
    1513    };
    1614
  • trunk/LayoutTests/inspector/model/stack-trace-expected.txt

    r239976 r288266  
    2121  10: _wrapCall - nativeCode (true) programCode (false)
    2222
     23-- Running test case: WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.Normal
     24PASS: Should be able to get the first non-native non-anonymous unblackboxed call frame.
     25
     26-- Running test case: WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.AllNative
     27PASS: Should not be able to get the first non-native non-anonymous unblackboxed call frame if the entire stack trace is native.
     28
     29-- Running test case: WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.AllBlackboxed
     30PASS: Should use the first blackboxed call frame if the entire stack trace is blackboxed.
     31
  • trunk/LayoutTests/inspector/model/stack-trace.html

    r236766 r288266  
    5353    });
    5454
     55    suite.addTestCase({
     56        name: "WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.Normal",
     57        async test() {
     58            let target = WI.mainTarget;
     59
     60            let sourceCode = new WI.SourceCode;
     61            let sourceCodeLocation = new WI.SourceCodeLocation(sourceCode, 0, 0);
     62
     63            let native1 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "native1", nativeCode: true});
     64            let native2 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "native2", nativeCode: true});
     65            let blackboxed1 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "blackboxed1", blackboxed: true});
     66            let blackboxed2 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "blackboxed2", blackboxed: true});
     67            let normal1 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "normal1"});
     68            let normal2 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "normal2"});
     69
     70            let stackTrace = new WI.StackTrace([native1, native2, blackboxed1, blackboxed2, normal1, normal2]);
     71            InspectorTest.expectEqual(stackTrace.firstNonNativeNonAnonymousNotBlackboxedCallFrame, normal1, "Should be able to get the first non-native non-anonymous unblackboxed call frame.");
     72        },
     73    });
     74
     75    suite.addTestCase({
     76        name: "WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.AllNative",
     77        async test() {
     78            let target = WI.mainTarget;
     79
     80            let sourceCode = new WI.SourceCode;
     81            let sourceCodeLocation = new WI.SourceCodeLocation(sourceCode, 0, 0);
     82
     83            let native1 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "native1", nativeCode: true});
     84            let native2 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "native2", nativeCode: true});
     85
     86            let stackTrace = new WI.StackTrace([native1, native2]);
     87            InspectorTest.expectNull(stackTrace.firstNonNativeNonAnonymousNotBlackboxedCallFrame, "Should not be able to get the first non-native non-anonymous unblackboxed call frame if the entire stack trace is native.");
     88        },
     89    });
     90
     91    suite.addTestCase({
     92        name: "WI.StackTrace.FirstNonNativeNonAnonymousNotBlackboxedCallFrame.AllBlackboxed",
     93        async test() {
     94            let target = WI.mainTarget;
     95
     96            let sourceCode = new WI.SourceCode;
     97            let sourceCodeLocation = new WI.SourceCodeLocation(sourceCode, 0, 0);
     98
     99            let blackboxed1 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "blackboxed1", blackboxed: true});
     100            let blackboxed2 = new WI.CallFrame(target, {sourceCodeLocation, functionName: "blackboxed2", blackboxed: true});
     101
     102            let stackTrace = new WI.StackTrace([blackboxed1, blackboxed2]);
     103            InspectorTest.expectEqual(stackTrace.firstNonNativeNonAnonymousNotBlackboxedCallFrame, blackboxed1, "Should use the first blackboxed call frame if the entire stack trace is blackboxed.");
     104        },
     105    });
     106
    55107    suite.runTestCasesAndFinish();
    56108}
  • trunk/Source/WebInspectorUI/ChangeLog

    r288243 r288266  
     12022-01-19  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: fully blackboxed stack traces don't show the right top call frame
     4        https://bugs.webkit.org/show_bug.cgi?id=235381
     5
     6        Reviewed by Patrick Angle.
     7
     8        * UserInterface/Models/StackTrace.js:
     9        (WI.StackTrace):
     10        (WI.StackTrace.fromPayload):
     11        (WI.StackTrace.prototype.get firstNonNativeNonAnonymousNotBlackboxedCallFrame):
     12        Only assign to `firstNonNativeNonAnonymousCallFrame` once.
     13        Drive-by: Don't re-fetch the blackbox data for the `WI.SourceCode` of the `WI.CallFrame`.
     14        Drive-by: Combine optional parameters into an `options = {}` for current code cleanliness
     15                  and greater flexibility for future changes.
     16
     17        * UserInterface/Models/CallFrame.js:
     18        (WI.CallFrame):
     19        (WI.CallFrame.fromDebuggerPayload):
     20        (WI.CallFrame.fromPayload):
     21        * UserInterface/Views/ThreadTreeElement.js:
     22        (WI.ThreadTreeElement.prototype.refresh):
     23        Drive-by: Combine optional parameters into an `options = {}` for current code cleanliness
     24                  and greater flexibility for future changes.
     25
     26        * UserInterface/Views/CallFrameTreeElement.js:
     27        (WI.CallFrameTreeElement):
     28        (WI.CallFrameTreeElement.prototype.onattach):
     29        * UserInterface/Views/CallFrameView.js:
     30        (WI.CallFrameView):
     31        Drive-by: Don't re-fetch the blackbox data for the `WI.SourceCode` of the `WI.CallFrame`.
     32
    1332022-01-19  Devin Rousso  <drousso@apple.com>
    234
  • trunk/Source/WebInspectorUI/UserInterface/Models/CallFrame.js

    r288030 r288266  
    2626WI.CallFrame = class CallFrame
    2727{
    28     constructor(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted, blackboxed)
    29     {
    30         console.assert(target instanceof WI.Target);
    31         console.assert(!sourceCodeLocation || sourceCodeLocation instanceof WI.SourceCodeLocation);
    32         console.assert(!thisObject || thisObject instanceof WI.RemoteObject);
    33         console.assert(!scopeChain || scopeChain instanceof Array);
     28    constructor(target, {id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted, blackboxed} = {})
     29    {
     30        console.assert(target instanceof WI.Target, target);
     31        console.assert(!sourceCodeLocation || sourceCodeLocation instanceof WI.SourceCodeLocation, sourceCodeLocation);
     32        console.assert(!thisObject || thisObject instanceof WI.RemoteObject, thisObject);
     33        console.assert(!scopeChain || scopeChain.every((item) => item instanceof WI.ScopeChainNode), scopeChain);
    3434
    3535        this._isConsoleEvaluation = sourceCodeLocation && isWebInspectorConsoleEvaluationScript(sourceCodeLocation.sourceCode.sourceURL);
     
    222222    static fromDebuggerPayload(target, payload, scopeChain, sourceCodeLocation)
    223223    {
    224         let id = payload.callFrameId;
    225         let thisObject = WI.RemoteObject.fromPayload(payload.this, target);
    226         let functionName = WI.CallFrame.functionNameFromPayload(payload);
    227         let nativeCode = false;
    228         let programCode = WI.CallFrame.programCodeFromPayload(payload);
    229         let isTailDeleted = payload.isTailDeleted;
    230         let blackboxed = sourceCodeLocation && !!WI.debuggerManager.blackboxDataForSourceCode(sourceCodeLocation.sourceCode);
    231         return new WI.CallFrame(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted, blackboxed);
     224        return new WI.CallFrame(target, {
     225            id: payload.callFrameId,
     226            sourceCodeLocation,
     227            functionName: WI.CallFrame.functionNameFromPayload(payload),
     228            thisObject: WI.RemoteObject.fromPayload(payload.this, target),
     229            scopeChain,
     230            programCode: WI.CallFrame.programCodeFromPayload(payload),
     231            isTailDeleted: payload.isTailDeleted,
     232            blackboxed: sourceCodeLocation && !!WI.debuggerManager.blackboxDataForSourceCode(sourceCodeLocation.sourceCode),
     233        });
    232234    }
    233235
     
    239241        let nativeCode = false;
    240242        let sourceCodeLocation = null;
    241         let functionName = WI.CallFrame.functionNameFromPayload(payload);
    242         let programCode = WI.CallFrame.programCodeFromPayload(payload);
    243243
    244244        if (url === "[native code]") {
     
    269269        }
    270270
    271         const id = null;
    272         const thisObject = null;
    273         const scopeChain = null;
    274         const isTailDeleted = false;
    275         let blackboxed = sourceCodeLocation && !!WI.debuggerManager.blackboxDataForSourceCode(sourceCodeLocation.sourceCode);
    276         return new WI.CallFrame(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted, blackboxed);
     271        return new WI.CallFrame(target, {
     272            sourceCodeLocation,
     273            functionName: WI.CallFrame.functionNameFromPayload(payload),
     274            nativeCode,
     275            programCode: WI.CallFrame.programCodeFromPayload(payload),
     276            blackboxed: sourceCodeLocation && !!WI.debuggerManager.blackboxDataForSourceCode(sourceCodeLocation.sourceCode),
     277        });
    277278    }
    278279};
  • trunk/Source/WebInspectorUI/UserInterface/Models/StackTrace.js

    r272139 r288266  
    2626WI.StackTrace = class StackTrace
    2727{
    28     constructor(callFrames, topCallFrameIsBoundary, truncated, parentStackTrace)
     28    constructor(callFrames, {topCallFrameIsBoundary, truncated, parentStackTrace} = {})
    2929    {
    30         console.assert(callFrames && callFrames.every((callFrame) => callFrame instanceof WI.CallFrame));
     30        console.assert(callFrames.every((callFrame) => callFrame instanceof WI.CallFrame), callFrames);
     31        console.assert(!parentStackTrace || parentStackTrace instanceof WI.StackTrace, parentStackTrace);
    3132
    3233        this._callFrames = callFrames;
     
    4546        while (payload) {
    4647            let callFrames = payload.callFrames.map((x) => WI.CallFrame.fromPayload(target, x));
    47             let stackTrace = new WI.StackTrace(callFrames, payload.topCallFrameIsBoundary, payload.truncated);
     48            let stackTrace = new WI.StackTrace(callFrames, {
     49                topCallFrameIsBoundary: payload.topCallFrameIsBoundary,
     50                truncated: payload.truncated,
     51            });
    4852            if (!result)
    4953                result = stackTrace;
     
    161165                // Save the first non-native non-anonymous call frame so it can be used as a
    162166                // fallback if all remaining call frames are blackboxed.
    163                 firstNonNativeNonAnonymousCallFrame = frame;
     167                firstNonNativeNonAnonymousCallFrame ??= frame;
     168            }
    164169
    165                 if (WI.debuggerManager.blackboxDataForSourceCode(sourceCode))
    166                     continue;
    167             }
     170            if (frame.blackboxed)
     171                continue;
    168172
    169173            return frame;
  • trunk/Source/WebInspectorUI/UserInterface/Views/CallFrameTreeElement.js

    r288243 r288266  
    5858        }
    5959
    60         this._isBlackboxed = WI.debuggerManager.blackboxDataForSourceCode(this._callFrame.sourceCodeLocation.sourceCode);
    61         if (this._isBlackboxed) {
     60        if (this._callFrame.blackboxed) {
    6261            this.addClassName("blackboxed");
    6362            this.tooltipHandledSeparately = true;
     
    9998
    10099            let tooltipSuffix = "";
    101             if (this._isBlackboxed)
     100            if (this._callFrame.blackboxed)
    102101                tooltipSuffix += "\n\n" + WI.UIString("Script ignored due to blackbox");
    103102
  • trunk/Source/WebInspectorUI/UserInterface/Views/CallFrameView.js

    r288030 r288266  
    3939        if (sourceCodeLocation) {
    4040            if (indicateIfBlackboxed)
    41                 callFrameElement.classList.toggle("blackboxed", WI.debuggerManager.blackboxDataForSourceCode(callFrame.sourceCodeLocation.sourceCode));
     41                callFrameElement.classList.toggle("blackboxed", callFrame.blackboxed);
    4242
    4343            WI.linkifyElement(callFrameElement, sourceCodeLocation, {
  • trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js

    r288243 r288266  
    7272            } else {
    7373                // Create a generic native CallFrame for the asynchronous boundary.
    74                 const functionName = WI.UIString("(async)");
    75                 const nativeCode = true;
    76                 boundaryCallFrame = new WI.CallFrame(null, null, null, functionName, null, null, nativeCode);
     74                boundaryCallFrame = new WI.CallFrame(this._target, {
     75                    functionName: WI.UIString("(async)"),
     76                    nativeCode: true,
     77                });
    7778            }
    7879
Note: See TracChangeset for help on using the changeset viewer.