void
HangMonitorParent::SendHangNotification(const HangData& aHangData,
                                        const nsString& aBrowserDumpId,
                                        bool aTakeMinidump)
{
  // chrome process, main thread
  MOZ_RELEASE_ASSERT(NS_IsMainThread());

  nsString dumpId;
  if ((aHangData.type() == HangData::TPluginHangData) && aTakeMinidump) {
    // We've been handed a partial minidump; complete it with plugin and
    // content process dumps.
    const PluginHangData& phd = aHangData.get_PluginHangData();
    plugins::TakeFullMinidump(phd.pluginId(), phd.contentProcessId(),
                              aBrowserDumpId, dumpId);
    UpdateMinidump(phd.pluginId(), dumpId);
  } else {
    // We already have a full minidump; go ahead and use it.
    dumpId = aBrowserDumpId;
  }

  mProcess->SetHangData(aHangData, dumpId);

  nsCOMPtr<nsIObserverService> observerService =
    mozilla::services::GetObserverService();
  observerService->NotifyObservers(mProcess, "process-hang-report", nullptr);
}
Example #2
0
bool
HangMonitorParent::RecvHangEvidence(const HangData& aHangData)
{
  // chrome process, background thread
  MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());

  if (!mReportHangs) {
    return true;
  }

#ifdef XP_WIN
  // Don't report hangs if we're debugging the process. You can comment this
  // line out for testing purposes.
  if (IsDebuggerPresent()) {
    return true;
  }
#endif

  // Before we wake up the browser main thread we want to take a
  // browser minidump.
  nsAutoString crashId;
#ifdef MOZ_CRASHREPORTER
  if (aHangData.type() == HangData::TPluginHangData) {
    MutexAutoLock lock(mBrowserCrashDumpHashLock);
    const PluginHangData& phd = aHangData.get_PluginHangData();
    if (!mBrowserCrashDumpIds.Get(phd.pluginId(), &crashId)) {
      nsCOMPtr<nsIFile> browserDump;
      if (CrashReporter::TakeMinidump(getter_AddRefs(browserDump), true)) {
        if (!CrashReporter::GetIDFromMinidump(browserDump, crashId) || crashId.IsEmpty()) {
          browserDump->Remove(false);
          NS_WARNING("Failed to generate timely browser stack, this is bad for plugin hang analysis!");
        } else {
          mBrowserCrashDumpIds.Put(phd.pluginId(), crashId);
        }
      }
    }
  }
#endif

  mHangMonitor->InitiateCPOWTimeout();

  MonitorAutoLock lock(mMonitor);

  nsCOMPtr<nsIRunnable> notifier =
    new HangObserverNotifier(mProcess, aHangData, crashId);
  NS_DispatchToMainThread(notifier);

  return true;
}
mozilla::ipc::IPCResult
HangMonitorParent::RecvHangEvidence(const HangData& aHangData)
{
  // chrome process, background thread
  MOZ_RELEASE_ASSERT(IsOnThread());

  if (!mReportHangs) {
    return IPC_OK();
  }

#ifdef XP_WIN
  // Don't report hangs if we're debugging the process. You can comment this
  // line out for testing purposes.
  if (IsDebuggerPresent()) {
    return IPC_OK();
  }
#endif

  // Before we wake up the browser main thread we want to take a
  // browser minidump.
  nsAutoString crashId;
  bool takeMinidump = false;
  if (aHangData.type() == HangData::TPluginHangData) {
    takeMinidump = TakeBrowserMinidump(aHangData.get_PluginHangData(), crashId);
  }

  mHangMonitor->InitiateCPOWTimeout();

  MonitorAutoLock lock(mMonitor);

  NS_DispatchToMainThread(
    mMainThreadTaskFactory.NewRunnableMethod(
      &HangMonitorParent::SendHangNotification, aHangData, crashId,
      takeMinidump));

  return IPC_OK();
}
bool
HangMonitorParent::RecvHangEvidence(const HangData& aHangData)
{
  // chrome process, background thread
  MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());

  if (!mReportHangs) {
    return true;
  }

#ifdef XP_WIN
  // Don't report hangs if we're debugging the process. You can comment this
  // line out for testing purposes.
  if (IsDebuggerPresent()) {
    return true;
  }
#endif

  // Before we wake up the browser main thread we want to take a
  // browser minidump.
  nsAutoString crashId;
  bool takeMinidump = false;
  if (aHangData.type() == HangData::TPluginHangData) {
    takeMinidump = TakeBrowserMinidump(aHangData.get_PluginHangData(), crashId);
  }

  mHangMonitor->InitiateCPOWTimeout();

  MonitorAutoLock lock(mMonitor);

  nsCOMPtr<nsIRunnable> notifier =
    new HangObserverNotifier(mProcess, this, aHangData, crashId, takeMinidump);
  NS_DispatchToMainThread(notifier);

  return true;
}