Backed out 2 changesets (bug 1594577) for build bustages at HangDetails.cpp. CLOSED TREE

Backed out changeset f7dae5e23628 (bug 1594577)
Backed out changeset bd42216f7b63 (bug 1594577)
This commit is contained in:
Brindusan Cristian 2019-11-16 00:43:29 +02:00
Родитель f1a64e2217
Коммит a401c2e994
8 изменённых файлов: 30 добавлений и 435 удалений

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

@ -5792,7 +5792,7 @@ mozilla::ipc::IPCResult ContentParent::RecvBHRThreadHang(
// XXX: We should be able to avoid this potentially expensive copy here by
// moving our deserialized argument.
nsCOMPtr<nsIHangDetails> hangDetails =
new nsHangDetails(HangDetails(aDetails), PersistedToDisk::No);
new nsHangDetails(HangDetails(aDetails));
obs->NotifyObservers(hangDetails, "bhr-thread-hang", nullptr);
}
return IPC_OK();

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

@ -269,7 +269,7 @@ mozilla::ipc::IPCResult GPUChild::RecvBHRThreadHang(
// XXX: We should be able to avoid this potentially expensive copy here by
// moving our deserialized argument.
nsCOMPtr<nsIHangDetails> hangDetails =
new nsHangDetails(HangDetails(aDetails), PersistedToDisk::No);
new nsHangDetails(HangDetails(aDetails));
obs->NotifyObservers(hangDetails, "bhr-thread-hang", nullptr);
}
return IPC_OK();

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

@ -6,7 +6,6 @@
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
ChromeUtils.defineModuleGetter(
this,
"TelemetryController",
@ -36,7 +35,6 @@ BHRTelemetryService.prototype = Object.freeze({
modules: [],
hangs: [],
};
this.clearPermahangFile = false;
},
recordHang({
@ -48,7 +46,6 @@ BHRTelemetryService.prototype = Object.freeze({
remoteType,
modules,
annotations,
wasPersisted,
}) {
if (!Services.telemetry.canRecordExtended) {
return;
@ -102,10 +99,6 @@ BHRTelemetryService.prototype = Object.freeze({
stack,
});
if (wasPersisted) {
this.clearPermahangFile = true;
}
// If we have collected enough hangs, we can submit the hangs we have
// collected to telemetry.
if (this.payload.hangs.length > this.TRANSMIT_HANG_COUNT) {
@ -114,13 +107,6 @@ BHRTelemetryService.prototype = Object.freeze({
},
submit() {
if (this.clearPermahangFile) {
OS.File.remove(
OS.Path.join(OS.Constants.Path.profileDir, "last_permahang.bin"),
{ ignoreAbsent: true }
);
}
if (!Services.telemetry.canRecordExtended) {
return;
}

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

@ -20,7 +20,6 @@
#include "prinrval.h"
#include "prthread.h"
#include "ThreadStackHelper.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIObserverService.h"
#include "nsIObserver.h"
#include "mozilla/Services.h"
@ -105,10 +104,6 @@ class BackgroundHangManager : public nsIObserver {
// Unwinding and reporting of hangs is despatched to this thread.
nsCOMPtr<nsIThread> mHangProcessingThread;
// Used for recording a permahang in case we don't ever make it back to
// the main thread to record/send it.
nsCOMPtr<nsIFile> mPermahangFile;
// Allows us to watch CPU usage and annotate hangs when the system is
// under high external load.
CPUUsageWatcher mCPUUsageWatcher;
@ -136,31 +131,13 @@ NS_IMPL_ISUPPORTS(BackgroundHangManager, nsIObserver)
NS_IMETHODIMP
BackgroundHangManager::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (!strcmp(aTopic, "browser-delayed-startup-finished")) {
MonitorAutoLock autoLock(mLock);
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(mPermahangFile));
if (NS_SUCCEEDED(rv)) {
mPermahangFile->AppendNative(NS_LITERAL_CSTRING("last_permahang.bin"));
} else {
mPermahangFile = nullptr;
}
NS_ENSURE_TRUE(!strcmp(aTopic, "profile-after-change"), NS_ERROR_UNEXPECTED);
BackgroundHangMonitor::DisableOnBeta();
if (mHangProcessingThread && mPermahangFile) {
nsCOMPtr<nsIRunnable> submitRunnable =
new SubmitPersistedPermahangRunnable(mPermahangFile);
mHangProcessingThread->Dispatch(submitRunnable.forget());
}
} else if (!strcmp(aTopic, "profile-after-change")) {
BackgroundHangMonitor::DisableOnBeta();
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
observerService->RemoveObserver(BackgroundHangManager::sInstance,
"profile-after-change");
} else {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
observerService->RemoveObserver(this, "profile-after-change");
return NS_OK;
}
@ -239,8 +216,7 @@ class BackgroundHangThread : public LinkedListElement<BackgroundHangThread> {
// Report a hang; aManager->mLock IS locked. The hang will be processed
// off-main-thread, and will then be submitted back.
void ReportHang(TimeDuration aHangTime,
PersistedToDisk aPersistedToDisk = PersistedToDisk::No);
void ReportHang(TimeDuration aHangTime);
// Report a permanent hang; aManager->mLock IS locked
void ReportPermaHang();
// Called by BackgroundHangMonitor::NotifyActivity
@ -492,8 +468,7 @@ BackgroundHangThread::~BackgroundHangThread() {
}
}
void BackgroundHangThread::ReportHang(TimeDuration aHangTime,
PersistedToDisk aPersistedToDisk) {
void BackgroundHangThread::ReportHang(TimeDuration aHangTime) {
// Recovered from a hang; called on the monitor thread
// mManager->mLock IS locked
@ -503,24 +478,17 @@ void BackgroundHangThread::ReportHang(TimeDuration aHangTime,
VoidString(), mThreadName, mRunnableName, std::move(mHangStack),
std::move(mAnnotations));
PersistedToDisk persistedToDisk = aPersistedToDisk;
if (aPersistedToDisk == PersistedToDisk::Yes && XRE_IsParentProcess()) {
auto res = WriteHangDetailsToFile(hangDetails, mManager->mPermahangFile);
persistedToDisk = res.isOk() ? PersistedToDisk::Yes : PersistedToDisk::No;
}
// If the hang processing thread exists, we can process the native stack
// on it. Otherwise, we are unable to report a native stack, so we just
// report without one.
if (mManager->mHangProcessingThread) {
nsCOMPtr<nsIRunnable> processHangStackRunnable =
new ProcessHangStackRunnable(std::move(hangDetails), persistedToDisk);
new ProcessHangStackRunnable(std::move(hangDetails));
mManager->mHangProcessingThread->Dispatch(
processHangStackRunnable.forget());
} else {
NS_WARNING("Unable to report native stack without a BHR processing thread");
RefPtr<nsHangDetails> hd =
new nsHangDetails(std::move(hangDetails), persistedToDisk);
RefPtr<nsHangDetails> hd = new nsHangDetails(std::move(hangDetails));
hd->Submit();
}
@ -541,11 +509,13 @@ void BackgroundHangThread::ReportPermaHang() {
// Permanently hanged; called on the monitor thread
// mManager->mLock IS locked
// The significance of a permahang is that it's likely that we won't ever
// recover and be allowed to submit this hang. On the parent thread, we
// compensate for this by writing the hang details to disk on this thread,
// and in our next session we'll try to read those details
ReportHang(mMaxTimeout, PersistedToDisk::Yes);
// NOTE: We used to capture a native stack in this situation if one had not
// already been captured, but with the new ReportHang design that is less
// practical.
//
// We currently don't look at hang reports outside of nightly, and already
// collect native stacks eagerly on nightly, so this should be OK.
ReportHang(mMaxTimeout);
}
MOZ_ALWAYS_INLINE void BackgroundHangThread::Update() {
@ -643,16 +613,17 @@ void BackgroundHangMonitor::Startup() {
return;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
if (!strcmp(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL), "beta")) {
if (XRE_IsParentProcess()) { // cached ClientID hasn't been read yet
BackgroundHangThread::Startup();
BackgroundHangManager::sInstance = new BackgroundHangManager();
Unused << NS_WARN_IF(
BackgroundHangManager::sInstance->mCPUUsageWatcher.Init().isErr());
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
observerService->AddObserver(BackgroundHangManager::sInstance,
"profile-after-change", false);
return;
@ -665,10 +636,6 @@ void BackgroundHangMonitor::Startup() {
BackgroundHangManager::sInstance = new BackgroundHangManager();
Unused << NS_WARN_IF(
BackgroundHangManager::sInstance->mCPUUsageWatcher.Init().isErr());
if (XRE_IsParentProcess()) {
observerService->AddObserver(BackgroundHangManager::sInstance,
"browser-delayed-startup-finished", false);
}
#endif
}
@ -681,11 +648,6 @@ void BackgroundHangMonitor::Shutdown() {
MOZ_ASSERT(BackgroundHangManager::sInstance, "Not initialized");
BackgroundHangManager::sInstance->mCPUUsageWatcher.Uninit();
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
observerService->RemoveObserver(BackgroundHangManager::sInstance,
"browser-delayed-startup-finished");
/* Scope our lock inside Shutdown() because the sInstance object can
be destroyed as soon as we set sInstance to nullptr below, and
we don't want to hold the lock when it's being destroyed. */

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

@ -12,22 +12,13 @@
#include "mozilla/dom/ContentParent.h" // For RemoteTypePrefix
#include "mozilla/Unused.h"
#include "mozilla/GfxMessageUtils.h" // For ParamTraits<GeckoProcessType>
#include "mozilla/ResultExtensions.h"
#ifdef MOZ_GECKO_PROFILER
# include "shared-libraries.h"
#endif
static const char MAGIC[] = "permahangsavev1";
namespace mozilla {
NS_IMETHODIMP
nsHangDetails::GetWasPersisted(bool* aWasPersisted) {
*aWasPersisted = mPersistedToDisk == PersistedToDisk::Yes;
return NS_OK;
}
NS_IMETHODIMP
nsHangDetails::GetDuration(double* aDuration) {
*aDuration = mDetails.duration().ToMilliseconds();
@ -385,319 +376,14 @@ void ReadModuleInformation(HangStack& stack) {
#endif
}
Result<Ok, nsresult> WriteUint(PRFileDesc* aFile, const CheckedUint32& aInt) {
if (!aInt.isValid()) {
MOZ_ASSERT_UNREACHABLE("Integer value out of bounds.");
return Err(NS_ERROR_UNEXPECTED);
}
int32_t value = aInt.value();
if (PR_Write(aFile, (void*)&value, sizeof(value)) != sizeof(value)) {
return Err(NS_ERROR_FAILURE);
}
return Ok();
}
Result<uint32_t, nsresult> ReadUint(PRFileDesc* aFile) {
int32_t value;
if (PR_Read(aFile, (void*)&value, sizeof(value)) != sizeof(value)) {
return Err(NS_ERROR_FAILURE);
}
return value;
}
Result<Ok, nsresult> WriteCString(PRFileDesc* aFile, const char* aString) {
size_t length = strlen(aString);
MOZ_TRY(WriteUint(aFile, CheckedUint32(length)));
if (PR_Write(aFile, (void*)aString, length) != length) {
return Err(NS_ERROR_FAILURE);
}
return Ok();
}
template <typename CharT>
Result<Ok, nsresult> WriteTString(PRFileDesc* aFile,
const nsTString<CharT>& aString) {
MOZ_TRY(WriteUint(aFile, CheckedUint32(aString.Length())));
size_t size = aString.Length() * sizeof(CharT);
if (PR_Write(aFile, (void*)aString.get(), size) != size) {
return Err(NS_ERROR_FAILURE);
}
return Ok();
}
template <typename CharT>
Result<nsTString<CharT>, nsresult> ReadTString(PRFileDesc* aFile) {
uint32_t length;
MOZ_TRY_VAR(length, ReadUint(aFile));
nsTString<CharT> result;
CharT buffer[512];
size_t bufferLength = sizeof(buffer) / sizeof(CharT);
while (length != 0) {
size_t toRead = std::min(bufferLength, size_t(length));
size_t toReadSize = toRead * sizeof(CharT);
if (PR_Read(aFile, (void*)buffer, toReadSize) != toReadSize) {
return Err(NS_ERROR_FAILURE);
}
if (!result.Append(buffer, toRead, mozilla::fallible)) {
return Err(NS_ERROR_FAILURE);
}
if (length > bufferLength) {
length -= bufferLength;
} else {
length = 0;
}
}
return result;
}
Result<Ok, nsresult> WriteEntry(PRFileDesc* aFile, const HangStack& aStack,
const HangEntry& aEntry) {
MOZ_TRY(WriteUint(aFile, uint32_t(aEntry.type())));
switch (aEntry.type()) {
case HangEntry::TnsCString: {
MOZ_TRY(WriteTString(aFile, aEntry.get_nsCString()));
break;
}
case HangEntry::THangEntryBufOffset: {
uint32_t offset = aEntry.get_HangEntryBufOffset().index();
if (NS_WARN_IF(aStack.strbuffer().IsEmpty() ||
offset >= aStack.strbuffer().Length())) {
MOZ_ASSERT_UNREACHABLE("Corrupted offset data");
return Err(NS_ERROR_FAILURE);
}
if (aStack.strbuffer().LastElement() != '\0') {
MOZ_ASSERT_UNREACHABLE("Corrupted strbuffer data");
return Err(NS_ERROR_FAILURE);
}
const char* start = (const char*)aStack.strbuffer().Elements() + offset;
MOZ_TRY(WriteCString(aFile, start));
break;
}
case HangEntry::THangEntryModOffset: {
const HangEntryModOffset& mo = aEntry.get_HangEntryModOffset();
MOZ_TRY(WriteUint(aFile, CheckedUint32(mo.module())));
MOZ_TRY(WriteUint(aFile, CheckedUint32(mo.offset())));
break;
}
case HangEntry::THangEntryProgCounter:
case HangEntry::THangEntryContent:
case HangEntry::THangEntryJit:
case HangEntry::THangEntryWasm:
case HangEntry::THangEntryChromeScript:
case HangEntry::THangEntrySuppressed: {
break;
}
default:
MOZ_CRASH("Unsupported HangEntry type?");
}
return Ok();
}
Result<Ok, nsresult> ReadEntry(PRFileDesc* aFile, HangStack& aStack) {
uint32_t type;
MOZ_TRY_VAR(type, ReadUint(aFile));
HangEntry::Type entryType = HangEntry::Type(type);
switch (entryType) {
case HangEntry::TnsCString:
case HangEntry::THangEntryBufOffset: {
nsCString str;
MOZ_TRY_VAR(str, ReadTString<char>(aFile));
aStack.stack().AppendElement(std::move(str));
break;
}
case HangEntry::THangEntryModOffset: {
uint32_t module;
MOZ_TRY_VAR(module, ReadUint(aFile));
uint32_t offset;
MOZ_TRY_VAR(offset, ReadUint(aFile));
aStack.stack().AppendElement(HangEntryModOffset(module, offset));
break;
}
case HangEntry::THangEntryProgCounter: {
aStack.stack().AppendElement(HangEntryProgCounter());
break;
}
case HangEntry::THangEntryContent: {
aStack.stack().AppendElement(HangEntryContent());
break;
}
case HangEntry::THangEntryJit: {
aStack.stack().AppendElement(HangEntryJit());
break;
}
case HangEntry::THangEntryWasm: {
aStack.stack().AppendElement(HangEntryWasm());
break;
}
case HangEntry::THangEntryChromeScript: {
aStack.stack().AppendElement(HangEntryChromeScript());
break;
}
case HangEntry::THangEntrySuppressed: {
aStack.stack().AppendElement(HangEntrySuppressed());
break;
}
default:
MOZ_CRASH("Unsupported HangEntry type?");
}
return Ok();
}
Result<HangDetails, nsresult> ReadHangDetailsFromFile(nsIFile* aFile) {
AutoFDClose fd;
nsresult rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0644, &fd.rwget());
if (NS_FAILED(rv)) {
return Err(rv);
}
uint8_t magicBuffer[sizeof(MAGIC)];
if (PR_Read(fd, (void*)magicBuffer, sizeof(MAGIC)) != sizeof(MAGIC)) {
return Err(NS_ERROR_FAILURE);
}
if (memcmp(magicBuffer, MAGIC, sizeof(MAGIC)) != 0) {
return Err(NS_ERROR_FAILURE);
}
HangDetails result;
uint32_t duration;
MOZ_TRY_VAR(duration, ReadUint(fd));
result.duration() = TimeDuration::FromMilliseconds(double(duration));
MOZ_TRY_VAR(result.threadName(), ReadTString<char>(fd));
MOZ_TRY_VAR(result.runnableName(), ReadTString<char>(fd));
MOZ_TRY_VAR(result.process(), ReadTString<char>(fd));
MOZ_TRY_VAR(result.remoteType(), ReadTString<char16_t>(fd));
uint32_t numAnnotations;
MOZ_TRY_VAR(numAnnotations, ReadUint(fd));
auto& annotations = result.annotations();
// Add a "Unrecovered" annotation so we can know when processing this that
// the hang persisted until the process was closed.
if (!annotations.SetCapacity(numAnnotations + 1, mozilla::fallible)) {
return Err(NS_ERROR_FAILURE);
}
annotations.AppendElement(HangAnnotation(NS_LITERAL_STRING("Unrecovered"),
NS_LITERAL_STRING("true")));
for (size_t i = 0; i < numAnnotations; ++i) {
HangAnnotation annot;
MOZ_TRY_VAR(annot.name(), ReadTString<char16_t>(fd));
MOZ_TRY_VAR(annot.value(), ReadTString<char16_t>(fd));
annotations.AppendElement(std::move(annot));
}
auto& stack = result.stack();
uint32_t numFrames;
MOZ_TRY_VAR(numFrames, ReadUint(fd));
if (!stack.stack().SetCapacity(numFrames, mozilla::fallible)) {
return Err(NS_ERROR_FAILURE);
}
for (size_t i = 0; i < numFrames; ++i) {
MOZ_TRY(ReadEntry(fd, stack));
}
uint32_t numModules;
MOZ_TRY_VAR(numModules, ReadUint(fd));
auto& modules = stack.modules();
if (!annotations.SetCapacity(numModules, mozilla::fallible)) {
return Err(NS_ERROR_FAILURE);
}
for (size_t i = 0; i < numModules; ++i) {
HangModule module;
MOZ_TRY_VAR(module.name(), ReadTString<char16_t>(fd));
MOZ_TRY_VAR(module.breakpadId(), ReadTString<char>(fd));
modules.AppendElement(std::move(module));
}
return result;
}
Result<Ok, nsresult> WriteHangDetailsToFile(HangDetails& aDetails,
nsIFile* aFile) {
AutoFDClose fd;
nsresult rv = aFile->OpenNSPRFileDesc(
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0644, &fd.rwget());
if (NS_FAILED(rv)) {
return Err(rv);
}
if (PR_Write(fd, (void*)MAGIC, sizeof(MAGIC)) != sizeof(MAGIC)) {
return Err(NS_ERROR_FAILURE);
}
double duration = aDetails.duration().ToMilliseconds();
if (duration > double(MaxValue<uint32_t>::value)) {
// Something has gone terribly wrong if we've hung for more than 2^32 ms.
return Err(NS_ERROR_FAILURE);
}
MOZ_TRY(WriteUint(fd, uint32_t(duration)));
MOZ_TRY(WriteTString(fd, aDetails.threadName()));
MOZ_TRY(WriteTString(fd, aDetails.runnableName()));
MOZ_TRY(WriteTString(fd, aDetails.process()));
MOZ_TRY(WriteTString(fd, aDetails.remoteType()));
MOZ_TRY(WriteUint(fd, CheckedUint32(aDetails.annotations().Length())));
for (auto& annot : aDetails.annotations()) {
MOZ_TRY(WriteTString(fd, annot.name()));
MOZ_TRY(WriteTString(fd, annot.value()));
}
auto& stack = aDetails.stack();
ReadModuleInformation(stack);
MOZ_TRY(WriteUint(fd, CheckedUint32(stack.stack().Length())));
for (auto& entry : stack.stack()) {
MOZ_TRY(WriteEntry(fd, stack, entry));
}
auto& modules = stack.modules();
MOZ_TRY(WriteUint(fd, CheckedUint32(modules.Length())));
for (auto& module : modules) {
MOZ_TRY(WriteTString(fd, module.name()));
MOZ_TRY(WriteTString(fd, module.breakpadId()));
}
return Ok();
}
NS_IMETHODIMP
ProcessHangStackRunnable::Run() {
// NOTE: Reading module information can take a long time, which is why we do
// it off-main-thread.
if (mHangDetails.stack().modules().IsEmpty()) {
ReadModuleInformation(mHangDetails.stack());
}
ReadModuleInformation(mHangDetails.stack());
RefPtr<nsHangDetails> hangDetails =
new nsHangDetails(std::move(mHangDetails), mPersistedToDisk);
hangDetails->Submit();
return NS_OK;
}
NS_IMETHODIMP
SubmitPersistedPermahangRunnable::Run() {
auto hangDetailsResult = ReadHangDetailsFromFile(mPermahangFile);
if (hangDetailsResult.isErr()) {
// If we somehow failed in trying to deserialize the hang file, go ahead
// and delete it to prevent future runs from having to go through the
// same thing. If we succeeded, however, the file should be cleaned up
// once the hang is submitted.
Unused << mPermahangFile->Remove(false);
return hangDetailsResult.unwrapErr();
}
RefPtr<nsHangDetails> hangDetails =
new nsHangDetails(hangDetailsResult.unwrap(), PersistedToDisk::Yes);
new nsHangDetails(std::move(mHangDetails));
hangDetails->Submit();
return NS_OK;

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

@ -10,7 +10,6 @@
#include "ipc/IPCMessageUtils.h"
#include "mozilla/ProcessedStack.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Result.h"
#include "mozilla/Move.h"
#include "mozilla/HangTypes.h"
#include "mozilla/HangAnnotations.h"
@ -20,11 +19,6 @@
namespace mozilla {
enum class PersistedToDisk {
No,
Yes,
};
/**
* HangDetails is the concrete implementaion of nsIHangDetails, and contains the
* infromation which we want to expose to observers of the bhr-thread-hang
@ -35,9 +29,8 @@ class nsHangDetails : public nsIHangDetails {
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIHANGDETAILS
explicit nsHangDetails(HangDetails&& aDetails,
PersistedToDisk aPersistedToDisk)
: mDetails(std::move(aDetails)), mPersistedToDisk(aPersistedToDisk) {}
explicit nsHangDetails(HangDetails&& aDetails)
: mDetails(std::move(aDetails)) {}
// Submit these HangDetails to the main thread. This will dispatch a runnable
// to the main thread which will fire off the bhr-thread-hang observer
@ -48,12 +41,8 @@ class nsHangDetails : public nsIHangDetails {
virtual ~nsHangDetails() {}
HangDetails mDetails;
PersistedToDisk mPersistedToDisk;
};
Result<Ok, nsresult> WriteHangDetailsToFile(HangDetails& aDetails,
nsIFile* aFile);
/**
* This runnable is run on the StreamTransportService threadpool in order to
* process the stack off main thread before submitting it to the main thread as
@ -64,34 +53,14 @@ Result<Ok, nsresult> WriteHangDetailsToFile(HangDetails& aDetails,
*/
class ProcessHangStackRunnable final : public Runnable {
public:
explicit ProcessHangStackRunnable(HangDetails&& aHangDetails,
PersistedToDisk aPersistedToDisk)
explicit ProcessHangStackRunnable(HangDetails&& aHangDetails)
: Runnable("ProcessHangStackRunnable"),
mHangDetails(std::move(aHangDetails)),
mPersistedToDisk(aPersistedToDisk) {}
mHangDetails(std::move(aHangDetails)) {}
NS_IMETHOD Run() override;
private:
HangDetails mHangDetails;
PersistedToDisk mPersistedToDisk;
};
/**
* This runnable handles checking whether our last session wrote a permahang to
* disk which we were unable to submit through telemetry. If so, we read the
* permahang out and try again to submit it.
*/
class SubmitPersistedPermahangRunnable final : public Runnable {
public:
explicit SubmitPersistedPermahangRunnable(nsIFile* aPermahangFile)
: Runnable("SubmitPersistedPermahangRunnable"),
mPermahangFile(aPermahangFile) {}
NS_IMETHOD Run() override;
private:
nsCOMPtr<nsIFile> mPermahangFile;
};
} // namespace mozilla

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

@ -20,12 +20,6 @@ class HangDetails;
[scriptable, uuid(23d63fff-38d6-4003-9c57-2c90aca1180a)]
interface nsIHangDetails : nsISupports
{
/**
* The hang was persisted to disk as a permahang, so we can clear the
* permahang file once we submit this.
*/
readonly attribute bool wasPersisted;
/**
* The detected duration of the hang in milliseconds.
*/

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

@ -153,5 +153,3 @@ The following annotations are currently present in tree:
+-----------------+-------------------------------------------------+
| HangUIDontShow | "true" if the hang UI was not shown |
+-----------------+-------------------------------------------------+
| Unrecovered | "true" if the hang persisted until process exit |
+-----------------+-------------------------------------------------+