EME Promises not cleaned up properly |
|
Issue descriptionIn b/110072353 a user reported a crash on Android when an app that uses encrypted media takes a long time to start up and they swiped it away as it took too long. The crash reported: [12528:12544:FATAL:ScriptPromiseResolver.h(57)] Check failed: state_ == kDetached || !is_promise_called_ || !GetScriptState()->ContextIsValid() || !GetExecutionContext() || GetExecutionContext()->IsContextDestroyed(). The current code in media:: has checks to make sure that the promise is fulfilled. However, once the blink:: promise is created, for many actions they are added to a queue that calls the media:: code later. So maybe some promise was created, but it is sitting in a queue. The app is torn down, and the items in the queue are simply destroyed. That could cause the ScriptPromiseResolver to get destroyed without ever being fulfilled. To test this out, I tried running the layout test encrypted-media-async-creation-with-gc.html after commenting out the handling of the timer queue. Get the same crash: [1:1:0615/154731.693041:FATAL:script_promise_resolver.h(57)] Check failed: state_ == kDetached || !is_promise_called_ || !GetScriptState()->ContextIsValid() || !GetExecutionContext() || GetExecutionContext()->IsContextDestroyed(). #0 0x7f3a68fd5a3d base::debug::StackTrace::StackTrace() #1 0x7f3a68d1f4bc base::debug::StackTrace::StackTrace() #2 0x7f3a68d8e51a logging::LogMessage::~LogMessage() #3 0x7f3a57fe7941 blink::ScriptPromiseResolver::~ScriptPromiseResolver() #4 0x7f3a54735544 blink::GarbageCollectedFinalized<>::FinalizeGarbageCollectedObject() #5 0x7f3a54735515 blink::FinalizerTraitImpl<>::Finalize() #6 0x7f3a547354f5 blink::FinalizerTrait<>::Finalize() #7 0x7f3a561f9f9e blink::HeapObjectHeader::Finalize() #8 0x7f3a562010b8 blink::NormalPage::Sweep() Will fix up the code so if the queue is destroyed while there are pending promises, the promises are rejected.
,
Jun 16 2018
More complicated than I thought. Can't simply update the destructor, as then the compiler complains with:
media_key_session.cc:200:5: error: [blink-gc] Finalizer '~PendingAction' accesses potentially finalized field 'result_'.
result_->CompleteWithError(kWebContentDecryptionModuleExceptionInvalidStateError, 0, "Operation aborted.");
^
media_key_session.cc:221:3: note: [blink-gc] Potentially finalized field 'result_' declared here:
Member<ContentDecryptionModuleResult> result_;
So I have to use a prefinalizer.
Using a prefinalizer fails, as rejecting the promise creates a DomException, which is not allowed during gc.
[1:1:0615/170254.300828:FATAL:v8_per_isolate_data.cc(52)] Check failed: !ScriptForbiddenScope::IsScriptForbidden().
#11 0x7f0dd54dc21b blink::ToV8()
#12 0x7f0dd557140f blink::V8ThrowDOMException::CreateDOMException()
#13 0x7f0dd1dafece blink::ContentDecryptionModuleResultPromise::Reject()
#14 0x7f0dd1db02da blink::ContentDecryptionModuleResultPromise::CompleteWithError()
#15 0x7f0dd1dbc579 blink::MediaKeySession::PendingAction::Dispose()
#16 0x7f0dd1dbc4ec blink::MediaKeySession::PendingAction::InvokePreFinalizer()
There is ScriptPromiseResolver::Detach(), so that might work as the object is going away anyway. The alternative might be to create the DomException at construction time, but that seems a waste to create something that will likely never be used.
,
Aug 27
Seems like the bug is not related to CDM. We have other crash with similar stack trace but there's no CDM activity. |
|
►
Sign in to add a comment |
|
Comment 1 by yucliu@chromium.org
, Jun 15 2018