Add an nsIGfxInfo for describing active crash guards. (bug 1270894 part 1, r=milan)

This commit is contained in:
David Anderson 2016-05-10 11:49:16 -07:00
Родитель cb99c2dc43
Коммит d180b0cc2a
5 изменённых файлов: 112 добавлений и 13 удалений

Просмотреть файл

@ -23,11 +23,24 @@ namespace mozilla {
namespace gfx {
static const size_t NUM_CRASH_GUARD_TYPES = size_t(CrashGuardType::NUM_TYPES);
static const char* sCrashGuardNames[NUM_CRASH_GUARD_TYPES] = {
static const char* sCrashGuardNames[] = {
"d3d11layers",
"d3d9video",
"glcontext",
"d3d11video",
};
static_assert(MOZ_ARRAY_LENGTH(sCrashGuardNames) == NUM_CRASH_GUARD_TYPES,
"CrashGuardType updated without a name string");
static inline void
BuildCrashGuardPrefName(CrashGuardType aType, nsCString& aOutPrefName)
{
MOZ_ASSERT(aType < CrashGuardType::NUM_TYPES);
MOZ_ASSERT(sCrashGuardNames[size_t(aType)]);
aOutPrefName.Assign("gfx.crash-guard.status.");
aOutPrefName.Append(sCrashGuardNames[size_t(aType)]);
}
DriverCrashGuard::DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aContentParent)
: mType(aType)
@ -36,10 +49,7 @@ DriverCrashGuard::DriverCrashGuard(CrashGuardType aType, dom::ContentParent* aCo
, mGuardActivated(false)
, mCrashDetected(false)
{
MOZ_ASSERT(mType < CrashGuardType::NUM_TYPES);
mStatusPref.Assign("gfx.crash-guard.status.");
mStatusPref.Append(sCrashGuardNames[size_t(mType)]);
BuildCrashGuardPrefName(aType, mStatusPref);
}
void
@ -53,15 +63,29 @@ DriverCrashGuard::InitializeIfNeeded()
Initialize();
}
void
DriverCrashGuard::Initialize()
static inline bool
AreCrashGuardsEnabled()
{
#ifdef NIGHTLY_BUILD
// We only use the crash guard on non-nightly channels, since the nightly
// channel is for development and having graphics features perma-disabled
// is rather annoying.
return;
return false;
#else
// Check to see if all guards have been disabled through the environment.
if (gfxEnv::DisableCrashGuard()) {
return false;
}
return true;
#endif
}
void
DriverCrashGuard::Initialize()
{
if (!AreCrashGuardsEnabled()) {
return;
}
// Using DriverCrashGuard off the main thread currently does not work. Under
// e10s it could conceivably work by dispatching the IPC calls via the main
@ -71,11 +95,6 @@ DriverCrashGuard::Initialize()
return;
}
// Check to see if all guards have been disabled through the environment.
if (gfxEnv::DisableCrashGuard()) {
return;
}
mGfxInfo = services::GetGfxInfo();
if (XRE_IsContentProcess()) {
@ -366,6 +385,31 @@ DriverCrashGuard::FlushPreferences()
}
}
void
DriverCrashGuard::ForEachActiveCrashGuard(const CrashGuardCallback& aCallback)
{
if (!AreCrashGuardsEnabled()) {
// Even if guards look active (via prefs), they can be ignored if globally
// disabled.
return;
}
for (size_t i = 0; i < NUM_CRASH_GUARD_TYPES; i++) {
CrashGuardType type = static_cast<CrashGuardType>(i);
nsCString prefName;
BuildCrashGuardPrefName(type, prefName);
auto status =
static_cast<DriverInitStatus>(Preferences::GetInt(prefName.get(), 0));
if (status != DriverInitStatus::Crashed) {
continue;
}
aCallback(sCrashGuardNames[i], prefName.get());
}
}
D3D11LayersCrashGuard::D3D11LayersCrashGuard(dom::ContentParent* aContentParent)
: DriverCrashGuard(CrashGuardType::D3D11Layers, aContentParent)
{

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsIGfxInfo.h"
#include "nsIFile.h"
#include "nsString.h"
#include "mozilla/Function.h"
#include <string>
namespace mozilla {
@ -40,6 +41,10 @@ enum class CrashGuardType : uint32_t
D3D9Video,
GLContext,
D3D11Video,
// Add new entries above this line, update the name array in
// DriverCrashGuard.cpp, and make sure to add an entry in
// ContentParent.cpp.
NUM_TYPES
};
@ -78,6 +83,10 @@ public:
Proxy
};
typedef mozilla::function<void(const char* aName, const char* aPrefName)>
CrashGuardCallback;
static void ForEachActiveCrashGuard(const CrashGuardCallback& aCallback);
protected:
virtual void Initialize();
virtual bool UpdateEnvironment() = 0;

Просмотреть файл

@ -34,6 +34,7 @@
#include "gfxPrefs.h"
#include "gfxPlatform.h"
#include "gfxConfig.h"
#include "DriverCrashGuard.h"
#if defined(MOZ_CRASHREPORTER)
#include "nsExceptionHandler.h"
@ -1337,6 +1338,35 @@ GfxInfoBase::InitFeatureObject(JSContext* aCx,
return true;
}
nsresult
GfxInfoBase::GetActiveCrashGuards(JSContext* aCx, JS::MutableHandle<JS::Value> aOut)
{
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
aOut.setObject(*array);
DriverCrashGuard::ForEachActiveCrashGuard([&](const char* aName,
const char* aPrefName) -> void {
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (!obj) {
return;
}
if (!SetJSPropertyString(aCx, obj, "type", aName)) {
return;
}
if (!SetJSPropertyString(aCx, obj, "prefName", aPrefName)) {
return;
}
if (!AppendJSElement(aCx, array, obj)) {
return;
}
});
return NS_OK;
}
GfxInfoCollectorBase::GfxInfoCollectorBase()
{
GfxInfoBase::AddCollector(this);

Просмотреть файл

@ -57,6 +57,7 @@ public:
NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD GetFeatureLog(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD GetActiveCrashGuards(JSContext*, JS::MutableHandle<JS::Value>) override;
// Initialization function. If you override this, you must call this class's
// version of Init first.

Просмотреть файл

@ -224,5 +224,20 @@ interface nsIGfxInfo : nsISupports
// }
[implicit_jscontext]
jsval getFeatures();
// Returns an array listing any active crash guards.
//
// [
// {
// // Type is one of "d3d11layers", "d3d9video", "glcontext",
// // or "d3d11video".
// "type": "<identifier>",
//
// // Preference that must be deleted/reset to retrigger the guard.
// "prefName": "<preference>",
// }
// ]
[implicit_jscontext]
jsval getActiveCrashGuards();
};