Bug 201713 - ASSERT NOT REACHED in Inspector::InjectedScriptModule::ensureInjected() seen with inspector/heap/getRemoteObject.html
Summary: ASSERT NOT REACHED in Inspector::InjectedScriptModule::ensureInjected() seen ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Devin Rousso
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-09-11 22:04 PDT by Ryan Haddad
Modified: 2020-04-30 10:20 PDT (History)
12 users (show)

See Also:


Attachments
Patch (21.11 KB, patch)
2019-09-17 07:34 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (22.01 KB, patch)
2019-09-17 22:06 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (22.12 KB, patch)
2019-09-19 01:30 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (21.79 KB, patch)
2019-09-19 08:09 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan Haddad 2019-09-11 22:04:24 PDT
The following flaky crash is seen with inspector/heap/getRemoteObject.html:

ERROR: File failed to delete. Error message: Operation not permitted
/Volumes/Data/slave/mojave-debug/build/Source/WTF/wtf/posix/FileSystemPOSIX.cpp(77) : bool WTF::FileSystemImpl::deleteFile(const WTF::String &)
Failed to parse/execute CommandLineAPI!
//# sourceURL=__InjectedScript_CommandLineAPIModuleSource.js?(function(InjectedScriptHost,inspectedGlobalObject,injectedScriptId,injectedScript,{RemoteObject,CommandLineAPI},CommandLineAPIHost){injectedScript._inspectObject=function(object){if(arguments.length===0)?return;let objectId=RemoteObject.create(object);let hints={};switch(RemoteObject.describe(object)){case"Database":var databaseId=CommandLineAPIHost.databaseId(object);if(databaseId)?hints.databaseId=databaseId;break;case"Storage":var storageId=CommandLineAPIHost.storageId(object);if(storageId)?hints.domStorageId=InjectedScriptHost.evaluate("("+storageId+")");break;}?CommandLineAPIHost.inspect(objectId,hints);};CommandLineAPI.getters["0"]=function(){return CommandLineAPIHost.inspectedObject();};CommandLineAPI.methods["copy"]=function(object){let string=null;let subtype=RemoteObject.subtype(object);if(subtype==="node")?string=object.outerHTML;else if(subtype==="regexp")?string=""+object;else if(injectedScript.isPrimitiveValue(object))?string=""+object;else if(typeof object==="symbol")?string=inspectedGlobalObject.String(object);else if(typeof object==="function")?string=""+object;else{try{string=inspectedGlobalObject.JSON.stringify(object,null,"  ");}catch{string=""+object;}}?CommandLineAPIHost.copyText(string);};CommandLineAPI.methods["getEventListeners"]=function(target){return CommandLineAPIHost.getEventListeners(target);};function normalizeEventTypes(types){if(types===undefined)?types=["mouse","key","touch","control","abort","blur","change","devicemotion","deviceorientation","error","focus","load","reset","resize","scroll","search","select","submit","unload"];else if(typeof types==="string")?types=[types];let result=[];for(let i=0;i<types.length;i++){if(types[i]==="mouse")?result.push("click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","mousewheel");else if(types[i]==="key")?result.push("keydown","keypress","keyup","textInput");else if(types[i]==="touch")?result.push("touchcancel","touchend","touchmove","touchstart");else if(types[i]==="control")?result.push("blur","change","focus","reset","resize","scroll","select","submit","zoom");else?result.push(types[i]);}?return result;}?function logEvent(event)?{inspectedGlobalObject.console.log(event.type,event);}?CommandLineAPI.methods["monitorEvents"]=function(object,types){if(!object||!object.addEventListener||!object.removeEventListener)?return;types=normalizeEventTypes(types);for(let i=0;i<types.length;++i){object.removeEventListener(types[i],logEvent,false);object.addEventListener(types[i],logEvent,false);}};CommandLineAPI.methods["unmonitorEvents"]=function(object,types){if(!object||!object.addEventListener||!object.removeEventListener)?return;types=normalizeEventTypes(types);for(let i=0;i<types.length;++i)?object.removeEventListener(types[i],logEvent,false);};if(inspectedGlobalObject.document&&inspectedGlobalObject.Node){function canQuerySelectorOnNode(node){return node&&InjectedScriptHost.subtype(node)==="node"&&(node.nodeType===inspectedGlobalObject.Node.ELEMENT_NODE||node.nodeType===inspectedGlobalObject.Node.DOCUMENT_NODE||node.nodeType===inspectedGlobalObject.Node.DOCUMENT_FRAGMENT_NODE);}?CommandLineAPI.methods["$"]=function(selector,start){if(canQuerySelectorOnNode(start))?return start.querySelector(selector);let result=inspectedGlobalObject.document.querySelector(selector);if(result)?return result;if(selector&&selector[0]!=="#"){result=inspectedGlobalObject.document.getElementById(selector);if(result){inspectedGlobalObject.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")",selector);return null;}}?return result;};CommandLineAPI.methods["$$"]=function(selector,start){if(canQuerySelectorOnNode(start))?return inspectedGlobalObject.Array.from(start.querySelectorAll(selector));return inspectedGlobalObject.Array.from(inspectedGlobalObject.document.querySelectorAll(selector));};CommandLineAPI.methods["$x"]=function(xpath,context){let doc=(context&&context.ownerDocument)||inspectedGlobalObject.document;let result=doc.evaluate(xpath,context||doc,null,inspectedGlobalObject.XPathResult.ANY_TYPE,null);switch(result.resultType){case inspectedGlobalObject.XPathResult.NUMBER_TYPE:return result.numberValue;case inspectedGlobalObject.XPathResult.STRING_TYPE:return result.stringValue;case inspectedGlobalObject.XPathResult.BOOLEAN_TYPE:return result.booleanValue;}?let nodes=[];let node=null;while(node=result.iterateNext())?nodes.push(node);return nodes;};}?for(let name in CommandLineAPI.methods)?CommandLineAPI.methods[name].toString=function(){return"function "+name+"() { [Command Line API] }";};})?
SHOULD NEVER BE REACHED
./inspector/InjectedScriptModule.cpp(80) : void Inspector::InjectedScriptModule::ensureInjected(Inspector::InjectedScriptManager *, const Inspector::InjectedScript &)
1   0x1b28d51e9 WTFCrash
2   0x1b28d7f3b WTFCrashWithInfo(int, char const*, char const*, int)
3   0x1b3a213d7 Inspector::InjectedScriptModule::ensureInjected(Inspector::InjectedScriptManager*, Inspector::InjectedScript const&)
4   0x19bd56565 WebCore::CommandLineAPIModule::injectIfNeeded(Inspector::InjectedScriptManager*, Inspector::InjectedScript const&)
5   0x19be4db48 WebCore::WebInjectedScriptManager::didCreateInjectedScript(Inspector::InjectedScript const&)
6   0x1b3a1ff10 Inspector::InjectedScriptManager::injectedScriptFor(JSC::ExecState*)
7   0x1b3af4560 Inspector::InspectorHeapAgent::getRemoteObject(WTF::String&, int, WTF::String const*, WTF::RefPtr<Inspector::Protocol::Runtime::RemoteObject, WTF::DumbPtrTraits<Inspector::Protocol::Runtime::RemoteObject> >&)
8   0x1b3a4393a Inspector::HeapBackendDispatcher::getRemoteObject(long, WTF::RefPtr<WTF::JSONImpl::Object, WTF::DumbPtrTraits<WTF::JSONImpl::Object> >&&)
9   0x1b3a4293b Inspector::HeapBackendDispatcher::dispatch(long, WTF::String const&, WTF::Ref<WTF::JSONImpl::Object, WTF::DumbPtrTraits<WTF::JSONImpl::Object> >&&)
10  0x1b3a2325b Inspector::BackendDispatcher::dispatch(WTF::String const&)
11  0x19bdf434c WebCore::InspectorController::dispatchMessageFromFrontend(WTF::String const&)
12  0x10ea7614c WebKit::WebPageInspectorTarget::sendMessageToTargetBackend(WTF::String const&)
13  0x10ea7699d WebKit::WebPageInspectorTargetController::sendMessageToTargetBackend(WTF::String const&, WTF::String const&)
14  0x10ebb1177 WebKit::WebPage::sendMessageToTargetBackend(WTF::String const&, WTF::String const&)
15  0x10ec36893 void IPC::callMemberFunctionImpl<WebKit::WebPage, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&), std::__1::tuple<WTF::String, WTF::String>, 0ul, 1ul>(WebKit::WebPage*, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&), std::__1::tuple<WTF::String, WTF::String>&&, std::__1::integer_sequence<unsigned long, 0ul, 1ul>)
16  0x10ec367a0 void IPC::callMemberFunction<WebKit::WebPage, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&), std::__1::tuple<WTF::String, WTF::String>, std::__1::integer_sequence<unsigned long, 0ul, 1ul> >(std::__1::tuple<WTF::String, WTF::String>&&, WebKit::WebPage*, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&))
17  0x10ec1220a void IPC::handleMessage<Messages::WebPage::SendMessageToTargetBackend, WebKit::WebPage, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&)>(IPC::Decoder&, WebKit::WebPage*, void (WebKit::WebPage::*)(WTF::String const&, WTF::String const&))
18  0x10ec09980 WebKit::WebPage::didReceiveWebPageMessage(IPC::Connection&, IPC::Decoder&)
19  0x10ebb8d38 WebKit::WebPage::didReceiveMessage(IPC::Connection&, IPC::Decoder&)
20  0x10d878d09 IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&)
21  0x10e7bd35d WebKit::WebProcess::didReceiveMessage(IPC::Connection&, IPC::Decoder&)
22  0x10d8016f9 IPC::Connection::dispatchMessage(IPC::Decoder&)
23  0x10d7fabab IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >)
24  0x10d802203 IPC::Connection::dispatchOneIncomingMessage()
25  0x10d81c7bb IPC::Connection::enqueueIncomingMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >)::$_7::operator()()
26  0x10d81c6d9 WTF::Detail::CallableWrapper<IPC::Connection::enqueueIncomingMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >)::$_7, void>::call()
27  0x1b2901cfa WTF::Function<void ()>::operator()() const
28  0x1b2972d63 WTF::RunLoop::performWork()
29  0x1b29741fe WTF::RunLoop::performWork(void*)
30  0x7fff3787c683 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
31  0x7fff3787c629 __CFRunLoopDoSource0

https://webkit-test-results.webkit.org/dashboards/flakiness_dashboard.html#showAllRuns=true&tests=inspector%2Fheap%2FgetRemoteObject.html
Comment 1 Radar WebKit Bug Importer 2019-09-11 22:04:38 PDT
<rdar://problem/55290349>
Comment 2 Joseph Pecoraro 2019-09-11 22:21:18 PDT
I think for this we have to add debugging to try and catch / log an exception. This must parse... so perhaps it is hitting an exception injecting the command line module source.
Comment 3 Devin Rousso 2019-09-17 07:34:24 PDT
Created attachment 378963 [details]
Patch
Comment 4 Devin Rousso 2019-09-17 07:36:45 PDT
Comment on attachment 378963 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=378963&action=review

> Source/JavaScriptCore/inspector/InjectedScriptManager.cpp:193
> +        WTFLogAlways("Error when creating injected script: %s", createResult.error().getString(inspectedExecState).ascii().data());

This doesn't actually log what the exception is about, and seems to just show an empty string.  JSC folks, am I doing this right?  How does one actually "get" the exception information as a string (e.g. "SyntaxError: ...")?

> Source/JavaScriptCore/inspector/InjectedScriptModule.cpp:70
> +        WTFLogAlways("Error when calling 'hasInjectedModule': %s", hasInjectedModuleResult.error().getString(injectedScript.scriptState()).ascii().data());

Ditto

> Source/JavaScriptCore/inspector/InjectedScriptModule.cpp:80
> +            WTFLogAlways("Error when calling 'injectModule': %s", injectModuleResult.error().getString(injectedScript.scriptState()).ascii().data());

Ditto
Comment 5 Joseph Pecoraro 2019-09-17 11:48:43 PDT
Comment on attachment 378963 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=378963&action=review

>> Source/JavaScriptCore/inspector/InjectedScriptManager.cpp:193
>> +        WTFLogAlways("Error when creating injected script: %s", createResult.error().getString(inspectedExecState).ascii().data());
> 
> This doesn't actually log what the exception is about, and seems to just show an empty string.  JSC folks, am I doing this right?  How does one actually "get" the exception information as a string (e.g. "SyntaxError: ...")?

I think you can try and get the JSValue to a JSC::Exception:

    auto* exception = jsDynamicCast<JSC::Exception*>(vm, exceptionValue);

Then something that takes an Exception and gets value out of it is `JSGlobalObjectInspectorController::reportAPIException` which does a toString of the `exception->value()`.
Comment 6 Devin Rousso 2019-09-17 22:06:03 PDT
Created attachment 379019 [details]
Patch

This logs the error text, as well as the line/column (which defaults to 0:0) and the full source text (since it's minified, meaning line/column won't match the original source).
Comment 7 Joseph Pecoraro 2019-09-18 11:32:53 PDT
Comment on attachment 379019 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=379019&action=review

r=me

> Source/JavaScriptCore/inspector/InjectedScriptModule.cpp:75
> +        WTFLogAlways("Error when calling 'hasInjectedModule' for '%s': %s (%d:%d)\n", name().ascii().data(), hasInjectedModuleResult.error().value().toWTFString(injectedScript.scriptState()).ascii().data(), line, column);

Why do we use `ascii().data()` instead of `utf8().data()`? That would at least have newlines.

> Source/JavaScriptCore/runtime/Exception.h:63
> +    JS_EXPORT_PRIVATE ~Exception();

Weird. Was this needed?
Comment 8 Devin Rousso 2019-09-19 01:30:04 PDT
Created attachment 379113 [details]
Patch
Comment 9 Devin Rousso 2019-09-19 01:30:39 PDT
Comment on attachment 379019 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=379019&action=review

>> Source/JavaScriptCore/inspector/InjectedScriptModule.cpp:75
>> +        WTFLogAlways("Error when calling 'hasInjectedModule' for '%s': %s (%d:%d)\n", name().ascii().data(), hasInjectedModuleResult.error().value().toWTFString(injectedScript.scriptState()).ascii().data(), line, column);
> 
> Why do we use `ascii().data()` instead of `utf8().data()`? That would at least have newlines.

I was using what was there previously.  We should totally use that instead :)

>> Source/JavaScriptCore/runtime/Exception.h:63
>> +    JS_EXPORT_PRIVATE ~Exception();
> 
> Weird. Was this needed?

Yeah, I got linker errors without this when compiling WebCore.
Comment 10 Mark Lam 2019-09-19 03:56:07 PDT
Comment on attachment 379113 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=379113&action=review

> Source/JavaScriptCore/inspector/InjectedScriptManager.cpp:146
> +Expected<JSC::JSObject*, Exception> InjectedScriptManager::createInjectedScript(const String& source, ExecState* scriptState, int id)

This is wrong.  Exception is a cell, and you should never pass a cell by value.  This is why you needed to export the destructor.  You shouldn't need to do that.  The destructor should only be called by the GC when there are no more references to this cell.  Can you return Expected<JSObject*, NakedPtr<Exception>> instead?

BTW, I don't think you need to specify the JSC:: namespace for JSObject here.  You don't have a another definition of JSObject, right?
Comment 11 Devin Rousso 2019-09-19 08:09:27 PDT
Created attachment 379134 [details]
Patch
Comment 12 WebKit Commit Bot 2019-09-20 01:27:32 PDT
The commit-queue encountered the following flaky tests while processing attachment 379134 [details]:

inspector/canvas/resolveContext-bitmaprenderer.html bug 202038 (author: drousso@apple.com)
The commit-queue is continuing to process your patch.
Comment 13 WebKit Commit Bot 2019-09-20 01:28:15 PDT
Comment on attachment 379134 [details]
Patch

Clearing flags on attachment: 379134

Committed r250124: <https://trac.webkit.org/changeset/250124>
Comment 14 WebKit Commit Bot 2019-09-20 01:28:17 PDT
All reviewed patches have been landed.  Closing bug.