Bug 1652613 - report slow script hang durations and only clear hang data after the observer notification, r=mconley

Differential Revision: https://phabricator.services.mozilla.com/D83989
This commit is contained in:
Gijs Kruitbosch 2020-07-23 22:12:16 +00:00
Родитель 8cc4eea7b7
Коммит a75ccccec2
7 изменённых файлов: 39 добавлений и 16 удалений

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

@ -4720,7 +4720,8 @@ void nsGlobalWindowInner::FireOfflineStatusEventIfChanged() {
nsGlobalWindowInner::SlowScriptResponse
nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx,
const nsString& aAddonId) {
const nsString& aAddonId,
const double aDuration) {
nsresult rv;
if (Preferences::GetBool("dom.always_stop_slow_scripts")) {
@ -4768,7 +4769,8 @@ nsGlobalWindowInner::ShowSlowScriptDialog(JSContext* aCx,
nsIDocShell* docShell = GetDocShell();
nsCOMPtr<nsIBrowserChild> child =
docShell ? docShell->GetBrowserChild() : nullptr;
action = monitor->NotifySlowScript(child, filename.get(), aAddonId);
action =
monitor->NotifySlowScript(child, filename.get(), aAddonId, aDuration);
if (action == ProcessHangMonitor::Terminate) {
return KillSlowScript;
}

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

@ -482,7 +482,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
KillScriptGlobal
};
SlowScriptResponse ShowSlowScriptDialog(JSContext* aCx,
const nsString& aAddonId);
const nsString& aAddonId,
const double aDuration);
// Inner windows only.
void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);

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

@ -20,6 +20,7 @@ struct SlowScriptData
TabId tabId;
nsCString filename;
nsString addonId;
double duration;
};
struct PluginHangData

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

@ -89,9 +89,10 @@ class HangMonitorChild : public PProcessHangMonitorChild,
typedef ProcessHangMonitor::SlowScriptAction SlowScriptAction;
SlowScriptAction NotifySlowScript(nsIBrowserChild* aBrowserChild,
const char* aFileName,
const nsString& aAddonId);
const nsString& aAddonId,
const double aDuration);
void NotifySlowScriptAsync(TabId aTabId, const nsCString& aFileName,
const nsString& aAddonId);
const nsString& aAddonId, const double aDuration);
bool IsDebuggerStartupComplete();
@ -589,15 +590,17 @@ void HangMonitorChild::Bind(Endpoint<PProcessHangMonitorChild>&& aEndpoint) {
void HangMonitorChild::NotifySlowScriptAsync(TabId aTabId,
const nsCString& aFileName,
const nsString& aAddonId) {
const nsString& aAddonId,
const double aDuration) {
if (mIPCOpen) {
Unused << SendHangEvidence(SlowScriptData(aTabId, aFileName, aAddonId));
Unused << SendHangEvidence(
SlowScriptData(aTabId, aFileName, aAddonId, aDuration));
}
}
HangMonitorChild::SlowScriptAction HangMonitorChild::NotifySlowScript(
nsIBrowserChild* aBrowserChild, const char* aFileName,
const nsString& aAddonId) {
const nsString& aAddonId, const double aDuration) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mSentReport = true;
@ -629,9 +632,10 @@ HangMonitorChild::SlowScriptAction HangMonitorChild::NotifySlowScript(
}
nsAutoCString filename(aFileName);
Dispatch(NewNonOwningRunnableMethod<TabId, nsCString, nsString>(
Dispatch(NewNonOwningRunnableMethod<TabId, nsCString, nsString, double>(
"HangMonitorChild::NotifySlowScriptAsync", this,
&HangMonitorChild::NotifySlowScriptAsync, id, filename, aAddonId));
&HangMonitorChild::NotifySlowScriptAsync, id, filename, aAddonId,
aDuration));
return SlowScriptAction::Continue;
}
@ -851,11 +855,12 @@ void HangMonitorParent::SendHangNotification(const HangData& aHangData,
void HangMonitorParent::ClearHangNotification() {
// chrome process, main thread
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mProcess->ClearHang();
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->NotifyObservers(mProcess, "clear-hang-report", nullptr);
mProcess->ClearHang();
}
// Take a minidump of the browser process if one wasn't already taken for the
@ -1007,6 +1012,17 @@ HangMonitoredProcess::GetHangType(uint32_t* aHangType) {
return NS_OK;
}
NS_IMETHODIMP
HangMonitoredProcess::GetHangDuration(double* aHangDuration) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (mHangData.type() != HangData::TSlowScriptData) {
*aHangDuration = -1;
} else {
*aHangDuration = mHangData.get_SlowScriptData().duration();
}
return NS_OK;
}
NS_IMETHODIMP
HangMonitoredProcess::GetScriptBrowser(Element** aBrowser) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -1267,10 +1283,10 @@ ProcessHangMonitor::Observe(nsISupports* aSubject, const char* aTopic,
ProcessHangMonitor::SlowScriptAction ProcessHangMonitor::NotifySlowScript(
nsIBrowserChild* aBrowserChild, const char* aFileName,
const nsString& aAddonId) {
const nsString& aAddonId, const double aDuration) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
return HangMonitorChild::Get()->NotifySlowScript(aBrowserChild, aFileName,
aAddonId);
aAddonId, aDuration);
}
bool ProcessHangMonitor::IsDebuggerStartupComplete() {

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

@ -70,7 +70,8 @@ class ProcessHangMonitor final : public nsIObserver {
};
SlowScriptAction NotifySlowScript(nsIBrowserChild* aBrowserChild,
const char* aFileName,
const nsString& aAddonId);
const nsString& aAddonId,
const double aDuration);
void NotifyPluginHang(uint32_t aPluginId);

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

@ -32,6 +32,8 @@ interface nsIHangReport : nsISupports
// Only valid for SLOW_SCRIPT reports.
readonly attribute Element scriptBrowser;
readonly attribute ACString scriptFileName;
// Duration of the hang so far.
readonly attribute double hangDuration;
readonly attribute AString addonId;
// For PLUGIN_HANGs, this field contains information about the plugin.

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

@ -701,8 +701,8 @@ bool XPCJSContext::InterruptCallback(JSContext* cx) {
}
// Show the prompt to the user, and kill if requested.
nsGlobalWindowInner::SlowScriptResponse response =
win->ShowSlowScriptDialog(cx, addonId);
nsGlobalWindowInner::SlowScriptResponse response = win->ShowSlowScriptDialog(
cx, addonId, self->mSlowScriptActualWait.ToMilliseconds());
if (response == nsGlobalWindowInner::KillSlowScript) {
if (Preferences::GetBool("dom.global_stop_script", true)) {
xpc::Scriptability::Get(global).Block();