mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1209385 - Crash GMPs that don't respond to GMPVideoDecoder::Reset(). r=jwwang
This commit is contained in:
parent
3fd903c9df
commit
a76b46867d
@ -606,10 +606,21 @@ GMPChild::GetGMPStorage()
|
|||||||
return mStorage;
|
return mStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static MOZ_NEVER_INLINE void
|
||||||
GMPChild::RecvCrashPluginNow()
|
CrashForApiTimeout()
|
||||||
{
|
{
|
||||||
MOZ_CRASH();
|
// Never inline so that crash reports are distinctive.
|
||||||
|
MOZ_CRASH("Bug 1209385; GMP API actor failed to respond.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPChild::RecvCrashPluginNow(const GMPCrashReason& aReason)
|
||||||
|
{
|
||||||
|
if (aReason == kGmpApiTimeout) {
|
||||||
|
CrashForApiTimeout();
|
||||||
|
} else {
|
||||||
|
MOZ_CRASH();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ private:
|
|||||||
ProcessId aOtherPid) override;
|
ProcessId aOtherPid) override;
|
||||||
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
|
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
|
||||||
|
|
||||||
virtual bool RecvCrashPluginNow() override;
|
virtual bool RecvCrashPluginNow(const GMPCrashReason& aReason) override;
|
||||||
virtual bool RecvBeginAsyncShutdown() override;
|
virtual bool RecvBeginAsyncShutdown() override;
|
||||||
virtual bool RecvCloseActive() override;
|
virtual bool RecvCloseActive() override;
|
||||||
|
|
||||||
|
@ -118,6 +118,18 @@ GMPContentParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
|||||||
CloseIfUnused();
|
CloseIfUnused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GMPContentParent::CrashPluginNow(GMPCrashReason aReason)
|
||||||
|
{
|
||||||
|
if (mParent) {
|
||||||
|
mParent->Crash(aReason);
|
||||||
|
} else {
|
||||||
|
nsRefPtr<GeckoMediaPluginServiceChild> gmp(
|
||||||
|
GeckoMediaPluginServiceChild::GetSingleton());
|
||||||
|
gmp->CrashPluginNow(mPluginId, aReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GMPContentParent::CloseIfUnused()
|
GMPContentParent::CloseIfUnused()
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "mozilla/gmp/PGMPContentParent.h"
|
#include "mozilla/gmp/PGMPContentParent.h"
|
||||||
#include "GMPSharedMemManager.h"
|
#include "GMPSharedMemManager.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
#include "GMPUtils.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
@ -61,6 +62,8 @@ public:
|
|||||||
return mPluginId;
|
return mPluginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashPluginNow(GMPCrashReason aReason);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~GMPContentParent();
|
~GMPContentParent();
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include "gmp-audio-codec.h"
|
#include "gmp-audio-codec.h"
|
||||||
#include "gmp-decryption.h"
|
#include "gmp-decryption.h"
|
||||||
|
|
||||||
|
#include "GMPUtils.h"
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -247,6 +249,13 @@ struct ParamTraits<GMPVideoCodec>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ParamTraits<mozilla::GMPCrashReason>
|
||||||
|
: public ContiguousEnumSerializer<mozilla::GMPCrashReason,
|
||||||
|
mozilla::kPrefChange,
|
||||||
|
mozilla::kInvalid>
|
||||||
|
{};
|
||||||
|
|
||||||
} // namespace IPC
|
} // namespace IPC
|
||||||
|
|
||||||
#endif // GMPMessageUtils_h_
|
#endif // GMPMessageUtils_h_
|
||||||
|
@ -119,10 +119,10 @@ GMPParent::Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GMPParent::Crash()
|
GMPParent::Crash(GMPCrashReason aReason)
|
||||||
{
|
{
|
||||||
if (mState != GMPStateNotLoaded) {
|
if (mState != GMPStateNotLoaded) {
|
||||||
unused << SendCrashPluginNow();
|
unused << SendCrashPluginNow(aReason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||||
|
#include "GMPUtils.h"
|
||||||
|
|
||||||
class nsIThread;
|
class nsIThread;
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ public:
|
|||||||
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
||||||
nsresult CloneFrom(const GMPParent* aOther);
|
nsresult CloneFrom(const GMPParent* aOther);
|
||||||
|
|
||||||
void Crash();
|
void Crash(GMPCrashReason aReason);
|
||||||
|
|
||||||
nsresult LoadProcess();
|
nsresult LoadProcess();
|
||||||
|
|
||||||
|
@ -215,6 +215,38 @@ GeckoMediaPluginServiceChild::UpdateTrialCreateState(const nsAString& aKeySystem
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GeckoMediaPluginServiceChild::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||||
|
{
|
||||||
|
if (NS_GetCurrentThread() != mGMPThread) {
|
||||||
|
mGMPThread->Dispatch(NS_NewRunnableMethodWithArgs<uint32_t, GMPCrashReason>(
|
||||||
|
this, &GeckoMediaPluginServiceChild::CrashPluginNow,
|
||||||
|
aPluginId, aReason), NS_DISPATCH_NORMAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Callback : public GetServiceChildCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Callback(uint32_t aPluginId, GMPCrashReason aReason)
|
||||||
|
: mPluginId(aPluginId)
|
||||||
|
, mReason(aReason)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Done(GMPServiceChild* aService) override
|
||||||
|
{
|
||||||
|
aService->SendCrashPluginNow(mPluginId, mReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t mPluginId;
|
||||||
|
GMPCrashReason mReason;
|
||||||
|
};
|
||||||
|
|
||||||
|
UniquePtr<GetServiceChildCallback> callback(new Callback(aPluginId, aReason));
|
||||||
|
GetServiceChild(Move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
|
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
|
||||||
const char* aTopic,
|
const char* aTopic,
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "mozilla/ipc/Transport.h"
|
#include "mozilla/ipc/Transport.h"
|
||||||
#include "mozilla/gmp/PGMPServiceChild.h"
|
#include "mozilla/gmp/PGMPServiceChild.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
|
#include "GMPUtils.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
@ -52,6 +53,8 @@ public:
|
|||||||
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
|
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
|
||||||
uint32_t aState) override;
|
uint32_t aState) override;
|
||||||
|
|
||||||
|
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||||
|
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
void SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild);
|
void SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild);
|
||||||
|
@ -511,7 +511,7 @@ GeckoMediaPluginServiceParent::CrashPlugins()
|
|||||||
|
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
for (size_t i = 0; i < mPlugins.Length(); i++) {
|
for (size_t i = 0; i < mPlugins.Length(); i++) {
|
||||||
mPlugins[i]->Crash();
|
mPlugins[i]->Crash(kPrefChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,6 +1221,19 @@ GeckoMediaPluginServiceParent::UpdateTrialCreateState(const nsAString& aKeySyste
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GeckoMediaPluginServiceParent::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
LOGD(("%s::%s(%u, %u)", __CLASS__, __FUNCTION__, aPluginId, aReason));
|
||||||
|
for (const auto& plugin : mPlugins) {
|
||||||
|
if (plugin->GetPluginId() == aPluginId) {
|
||||||
|
plugin->Crash(aReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ExtractHostName(const nsACString& aOrigin, nsACString& aOutData)
|
ExtractHostName(const nsACString& aOrigin, nsACString& aOutData)
|
||||||
{
|
{
|
||||||
@ -1555,6 +1568,14 @@ GMPServiceParent::~GMPServiceParent()
|
|||||||
new DeleteTask<Transport>(GetTransport()));
|
new DeleteTask<Transport>(GetTransport()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPServiceParent::RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||||
|
const GMPCrashReason& aReason)
|
||||||
|
{
|
||||||
|
mService->CrashPluginNow(aPluginId, aReason);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
|
GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
|
||||||
const nsCString& aAPI,
|
const nsCString& aAPI,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
#include "GMPUtils.h"
|
||||||
|
|
||||||
template <class> struct already_AddRefed;
|
template <class> struct already_AddRefed;
|
||||||
|
|
||||||
@ -57,6 +58,8 @@ public:
|
|||||||
void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState);
|
void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState);
|
||||||
#endif // MOZ_CRASHREPORTER
|
#endif // MOZ_CRASHREPORTER
|
||||||
|
|
||||||
|
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class GMPServiceParent;
|
friend class GMPServiceParent;
|
||||||
|
|
||||||
@ -223,6 +226,8 @@ public:
|
|||||||
nsCString* aVersion);
|
nsCString* aVersion);
|
||||||
virtual bool RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
|
virtual bool RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
|
||||||
const uint32_t& aState) override;
|
const uint32_t& aState) override;
|
||||||
|
virtual bool RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||||
|
const GMPCrashReason& aReason) override;
|
||||||
|
|
||||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
|
||||||
|
@ -37,6 +37,12 @@ SplitAt(const char* aDelims,
|
|||||||
nsCString
|
nsCString
|
||||||
ToBase64(const nsTArray<uint8_t>& aBytes);
|
ToBase64(const nsTArray<uint8_t>& aBytes);
|
||||||
|
|
||||||
|
enum GMPCrashReason {
|
||||||
|
kPrefChange, // media.gmp.plugin.crash has been toggled.
|
||||||
|
kGmpApiTimeout, // Some API did not respond.
|
||||||
|
kInvalid,
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -188,6 +188,7 @@ GMPVideoDecoderParent::Reset()
|
|||||||
LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get()));
|
LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get()));
|
||||||
self->mResetCompleteTimeout = nullptr;
|
self->mResetCompleteTimeout = nullptr;
|
||||||
LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()"));
|
LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()"));
|
||||||
|
self->mPlugin->CrashPluginNow(kGmpApiTimeout);
|
||||||
});
|
});
|
||||||
CancelResetCompleteTimeout();
|
CancelResetCompleteTimeout();
|
||||||
mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread());
|
mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread());
|
||||||
|
@ -9,6 +9,7 @@ include protocol PGMPTimer;
|
|||||||
include protocol PGMPStorage;
|
include protocol PGMPStorage;
|
||||||
|
|
||||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||||
|
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
@ -33,7 +34,7 @@ parent:
|
|||||||
|
|
||||||
child:
|
child:
|
||||||
async BeginAsyncShutdown();
|
async BeginAsyncShutdown();
|
||||||
async CrashPluginNow();
|
async CrashPluginNow(GMPCrashReason aReason);
|
||||||
intr StartPlugin();
|
intr StartPlugin();
|
||||||
async SetNodeId(nsCString nodeId);
|
async SetNodeId(nsCString nodeId);
|
||||||
async CloseActive();
|
async CloseActive();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
include protocol PGMP;
|
include protocol PGMP;
|
||||||
|
|
||||||
using base::ProcessId from "base/process.h";
|
using base::ProcessId from "base/process.h";
|
||||||
|
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
@ -23,6 +24,8 @@ parent:
|
|||||||
returns (nsCString id);
|
returns (nsCString id);
|
||||||
|
|
||||||
async UpdateGMPTrialCreateState(nsString keySystem, uint32_t status);
|
async UpdateGMPTrialCreateState(nsString keySystem, uint32_t status);
|
||||||
|
|
||||||
|
async CrashPluginNow(uint32_t pluginId, GMPCrashReason aReason);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gmp
|
} // namespace gmp
|
||||||
|
Loading…
Reference in New Issue
Block a user