tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

UtilityProcessParent.cpp (6921B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 #include "mozilla/ipc/UtilityProcessParent.h"
      7 #include "mozilla/GeckoTrace.h"
      8 #include "mozilla/ipc/UtilityProcessManager.h"
      9 
     10 #if defined(XP_WIN)
     11 #  include <dwrite.h>
     12 #  include <process.h>
     13 #  include "mozilla/WinDllServices.h"
     14 #endif
     15 
     16 #include "mozilla/ipc/ProcessChild.h"
     17 #include "mozilla/FOGIPC.h"
     18 
     19 #include "mozilla/Telemetry.h"
     20 #include "mozilla/TelemetryIPC.h"
     21 
     22 #include "nsHashPropertyBag.h"
     23 #include "mozilla/Services.h"
     24 #include "nsIObserverService.h"
     25 
     26 namespace mozilla::ipc {
     27 
     28 UtilityProcessParent::UtilityProcessParent(UtilityProcessHost* aHost)
     29    : mHost(aHost) {
     30  MOZ_ASSERT(NS_IsMainThread());
     31  MOZ_ASSERT(mHost);
     32 }
     33 
     34 UtilityProcessParent::~UtilityProcessParent() = default;
     35 
     36 bool UtilityProcessParent::SendRequestMemoryReport(
     37    const uint32_t& aGeneration, const bool& aAnonymize,
     38    const bool& aMinimizeMemoryUsage, const Maybe<FileDescriptor>& aDMDFile) {
     39  mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration);
     40 
     41  PUtilityProcessParent::SendRequestMemoryReport(
     42      aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile,
     43      [self = RefPtr{this}](const uint32_t& aGeneration2) {
     44        if (self->mMemoryReportRequest) {
     45          self->mMemoryReportRequest->Finish(aGeneration2);
     46          self->mMemoryReportRequest = nullptr;
     47        }
     48      },
     49      [self = RefPtr{this}](mozilla::ipc::ResponseRejectReason) {
     50        self->mMemoryReportRequest = nullptr;
     51      });
     52 
     53  return true;
     54 }
     55 
     56 mozilla::ipc::IPCResult UtilityProcessParent::RecvAddMemoryReport(
     57    const MemoryReport& aReport) {
     58  if (mMemoryReportRequest) {
     59    mMemoryReportRequest->RecvReport(aReport);
     60  }
     61  return IPC_OK();
     62 }
     63 
     64 mozilla::ipc::IPCResult UtilityProcessParent::RecvFOGData(ByteBuf&& aBuf) {
     65  glean::FOGData(std::move(aBuf));
     66  return IPC_OK();
     67 }
     68 
     69 mozilla::ipc::IPCResult UtilityProcessParent::RecvGeckoTraceExport(
     70    ByteBuf&& aBuf) {
     71  recv_gecko_trace_export(aBuf.mData, aBuf.mLen);
     72  return IPC_OK();
     73 }
     74 
     75 #if defined(XP_WIN)
     76 mozilla::ipc::IPCResult UtilityProcessParent::RecvGetModulesTrust(
     77    ModulePaths&& aModPaths, bool aRunAtNormalPriority,
     78    GetModulesTrustResolver&& aResolver) {
     79  RefPtr<DllServices> dllSvc(DllServices::Get());
     80  dllSvc->GetModulesTrust(std::move(aModPaths), aRunAtNormalPriority)
     81      ->Then(
     82          GetMainThreadSerialEventTarget(), __func__,
     83          [aResolver](ModulesMapResult&& aResult) {
     84            aResolver(Some(ModulesMapResult(std::move(aResult))));
     85          },
     86          [aResolver](nsresult aRv) { aResolver(Nothing()); });
     87  return IPC_OK();
     88 }
     89 #endif  // defined(XP_WIN)
     90 
     91 mozilla::ipc::IPCResult UtilityProcessParent::RecvAccumulateChildHistograms(
     92    nsTArray<HistogramAccumulation>&& aAccumulations) {
     93  TelemetryIPC::AccumulateChildHistograms(Telemetry::ProcessID::Utility,
     94                                          aAccumulations);
     95  return IPC_OK();
     96 }
     97 
     98 mozilla::ipc::IPCResult
     99 UtilityProcessParent::RecvAccumulateChildKeyedHistograms(
    100    nsTArray<KeyedHistogramAccumulation>&& aAccumulations) {
    101  TelemetryIPC::AccumulateChildKeyedHistograms(Telemetry::ProcessID::Utility,
    102                                               aAccumulations);
    103  return IPC_OK();
    104 }
    105 
    106 mozilla::ipc::IPCResult UtilityProcessParent::RecvUpdateChildScalars(
    107    nsTArray<ScalarAction>&& aScalarActions) {
    108  TelemetryIPC::UpdateChildScalars(Telemetry::ProcessID::Utility,
    109                                   aScalarActions);
    110  return IPC_OK();
    111 }
    112 
    113 mozilla::ipc::IPCResult UtilityProcessParent::RecvUpdateChildKeyedScalars(
    114    nsTArray<KeyedScalarAction>&& aScalarActions) {
    115  TelemetryIPC::UpdateChildKeyedScalars(Telemetry::ProcessID::Utility,
    116                                        aScalarActions);
    117  return IPC_OK();
    118 }
    119 
    120 mozilla::ipc::IPCResult UtilityProcessParent::RecvRecordChildEvents(
    121    nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents) {
    122  TelemetryIPC::RecordChildEvents(Telemetry::ProcessID::Utility, aEvents);
    123  return IPC_OK();
    124 }
    125 
    126 mozilla::ipc::IPCResult UtilityProcessParent::RecvRecordDiscardedData(
    127    const mozilla::Telemetry::DiscardedData& aDiscardedData) {
    128  TelemetryIPC::RecordDiscardedData(Telemetry::ProcessID::Utility,
    129                                    aDiscardedData);
    130  return IPC_OK();
    131 }
    132 
    133 mozilla::ipc::IPCResult UtilityProcessParent::RecvInitCompleted() {
    134  MOZ_ASSERT(mHost);
    135  mHost->ResolvePromise();
    136  return IPC_OK();
    137 }
    138 
    139 void UtilityProcessParent::ActorDestroy(ActorDestroyReason aWhy) {
    140  RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
    141 
    142  if (aWhy == AbnormalShutdown) {
    143    nsAutoString dumpID;
    144 
    145    if (mCrashReporter) {
    146 #if defined(MOZ_SANDBOX)
    147      RefPtr<mozilla::ipc::UtilityProcessManager> upm =
    148          mozilla::ipc::UtilityProcessManager::GetSingleton();
    149      if (upm) {
    150        Span<const UtilityActorName> actors = upm->GetActors(this);
    151        nsAutoCString actorsName;
    152        if (!actors.IsEmpty()) {
    153          actorsName += GetUtilityActorName(actors.First<1>()[0]);
    154          for (const auto& actor : actors.From(1)) {
    155            actorsName += ", "_ns + GetUtilityActorName(actor);
    156          }
    157        }
    158        mCrashReporter->AddAnnotationNSCString(
    159            CrashReporter::Annotation::UtilityActorsName, actorsName);
    160      }
    161 #endif
    162    }
    163 
    164    GenerateCrashReport(&dumpID);
    165 
    166    // It's okay for dumpID to be empty if there was no minidump generated
    167    // tests like ipc/glue/test/browser/browser_utility_crashReporter.js are
    168    // there to verify this
    169    if (!dumpID.IsEmpty()) {
    170      props->SetPropertyAsAString(u"dumpID"_ns, dumpID);
    171    }
    172 
    173    MaybeTerminateProcess();
    174  }
    175 
    176  nsAutoString pid;
    177  pid.AppendInt(static_cast<uint64_t>(OtherPid()));
    178 
    179  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
    180  if (obs) {
    181    obs->NotifyObservers((nsIPropertyBag2*)props, "ipc:utility-shutdown",
    182                         pid.get());
    183  } else {
    184    NS_WARNING("Could not get a nsIObserverService, ipc:utility-shutdown skip");
    185  }
    186 
    187  mHost->OnChannelClosed(aWhy);
    188 }
    189 
    190 // To ensure that IPDL is finished before UtilityParent gets deleted.
    191 class DeferredDeleteUtilityProcessParent : public Runnable {
    192 public:
    193  explicit DeferredDeleteUtilityProcessParent(
    194      RefPtr<UtilityProcessParent> aParent)
    195      : Runnable("ipc::glue::DeferredDeleteUtilityProcessParent"),
    196        mParent(std::move(aParent)) {}
    197 
    198  NS_IMETHODIMP Run() override { return NS_OK; }
    199 
    200 private:
    201  RefPtr<UtilityProcessParent> mParent;
    202 };
    203 
    204 /* static */
    205 void UtilityProcessParent::Destroy(RefPtr<UtilityProcessParent> aParent) {
    206  NS_DispatchToMainThread(
    207      new DeferredDeleteUtilityProcessParent(std::move(aParent)));
    208 }
    209 
    210 }  // namespace mozilla::ipc