mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1074952 - Part 4. For the critical log, save the first, then circular buffer the rest into the crash annotations. r=bas
This commit is contained in:
parent
7ece31d5c9
commit
d8d778d935
@ -11,6 +11,7 @@
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for GfxMemoryImageReporter
|
||||
|
||||
#include "prlog.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxPrefs.h"
|
||||
@ -152,22 +153,103 @@ public:
|
||||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
/// This override of the LogForwarder, initially used for the critical graphics
|
||||
/// errors, is sending the log to the crash annotations as well, but only
|
||||
/// if the capacity set with the method below is >= 2. We always retain the
|
||||
/// very first critical message, and the latest capacity-1 messages are
|
||||
/// rotated through. Note that we don't expect the total number of times
|
||||
/// this gets called to be large - it is meant for critical errors only.
|
||||
|
||||
class CrashStatsLogForwarder: public mozilla::gfx::LogForwarder
|
||||
{
|
||||
public:
|
||||
virtual void Log(const std::string& aString) MOZ_OVERRIDE {
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
nsCString reportString(aString.c_str());
|
||||
CrashReporter::AppendAppNotesToCrashReport(reportString);
|
||||
#else
|
||||
printf("GFX ERROR: %s", aString.c_str());
|
||||
#endif
|
||||
}
|
||||
CrashStatsLogForwarder(const char* aKey);
|
||||
virtual void Log(const std::string& aString) MOZ_OVERRIDE;
|
||||
|
||||
void SetCircularBufferSize(uint32_t aCapacity);
|
||||
|
||||
private:
|
||||
// Helpers for the Log()
|
||||
bool UpdateStringsVector(const std::string& aString);
|
||||
void UpdateCrashReport();
|
||||
|
||||
private:
|
||||
std::vector<std::pair<int32_t,std::string> > mBuffer;
|
||||
nsCString mCrashCriticalKey;
|
||||
uint32_t mMaxCapacity;
|
||||
int32_t mIndex;
|
||||
};
|
||||
|
||||
CrashStatsLogForwarder::CrashStatsLogForwarder(const char* aKey)
|
||||
: mBuffer()
|
||||
, mCrashCriticalKey(aKey)
|
||||
, mMaxCapacity(0)
|
||||
, mIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void CrashStatsLogForwarder::SetCircularBufferSize(uint32_t aCapacity)
|
||||
{
|
||||
mMaxCapacity = aCapacity;
|
||||
mBuffer.reserve(static_cast<size_t>(aCapacity));
|
||||
}
|
||||
|
||||
bool
|
||||
CrashStatsLogForwarder::UpdateStringsVector(const std::string& aString)
|
||||
{
|
||||
// We want at least the first one and the last one. Otherwise, no point.
|
||||
if (mMaxCapacity < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mIndex += 1;
|
||||
MOZ_ASSERT(mIndex >= 0);
|
||||
|
||||
// index will count 0, 1, 2, ..., max-1, 1, 2, ..., max-1, 1, 2, ...
|
||||
int32_t index = mIndex ? (mIndex-1) % (mMaxCapacity-1) + 1 : 0;
|
||||
MOZ_ASSERT(index >= 0 && index < (int32_t)mMaxCapacity);
|
||||
MOZ_ASSERT(index <= mIndex && index <= (int32_t)mBuffer.size());
|
||||
|
||||
// Checking for index >= mBuffer.size(), rather than index == mBuffer.size()
|
||||
// just out of paranoia, but we know index <= mBuffer.size().
|
||||
std::pair<int32_t,std::string> newEntry(mIndex,aString);
|
||||
if (index >= static_cast<int32_t>(mBuffer.size())) {
|
||||
mBuffer.push_back(newEntry);
|
||||
} else {
|
||||
mBuffer[index] = newEntry;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CrashStatsLogForwarder::UpdateCrashReport()
|
||||
{
|
||||
std::stringstream message;
|
||||
for(std::vector<std::pair<int32_t, std::string> >::iterator it = mBuffer.begin(); it != mBuffer.end(); ++it) {
|
||||
message << "|[" << (*it).first << "]" << (*it).second;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
nsCString reportString(message.str().c_str());
|
||||
nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
|
||||
#else
|
||||
nsresult annotated = NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
if (annotated != NS_OK) {
|
||||
printf("Crash Annotation %s: %s",
|
||||
mCrashCriticalKey.get(), message.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CrashStatsLogForwarder::Log(const std::string& aString)
|
||||
{
|
||||
if (UpdateStringsVector(aString)) {
|
||||
UpdateCrashReport();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(SRGBOverrideObserver, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
#define GFX_DOWNLOADABLE_FONTS_ENABLED "gfx.downloadable_fonts.enabled"
|
||||
@ -358,11 +440,14 @@ gfxPlatform::Init()
|
||||
}
|
||||
gEverInitialized = true;
|
||||
|
||||
mozilla::gfx::Factory::SetLogForwarder(new CrashStatsLogForwarder);
|
||||
CrashStatsLogForwarder* logForwarder = new CrashStatsLogForwarder("GraphicsCriticalError");
|
||||
mozilla::gfx::Factory::SetLogForwarder(logForwarder);
|
||||
|
||||
// Initialize the preferences by creating the singleton.
|
||||
gfxPrefs::GetSingleton();
|
||||
|
||||
logForwarder->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
|
||||
|
||||
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
@ -530,6 +615,9 @@ gfxPlatform::Shutdown()
|
||||
mozilla::gl::GLContextProviderEGL::Shutdown();
|
||||
#endif
|
||||
|
||||
// This is a bit iffy - we're assuming that we were the ones that set the
|
||||
// log forwarder in the Factory, so that it's our responsibility to
|
||||
// delete it.
|
||||
delete mozilla::gfx::Factory::GetLogForwarder();
|
||||
mozilla::gfx::Factory::SetLogForwarder(nullptr);
|
||||
|
||||
|
@ -209,6 +209,8 @@ private:
|
||||
DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels", GrallocFenceWithReadPixels, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456);
|
||||
// Note that "gfx.logging.level" is defined in Logging.h
|
||||
DECL_GFX_PREF(Once, "gfx.logging.crash.length", GfxLoggingCrashLength, uint32_t, 6);
|
||||
DECL_GFX_PREF(Live, "gfx.perf-warnings.enabled", PerfWarnings, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user