1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef __mozilla_ProcInfo_h
7 #define __mozilla_ProcInfo_h
9 #include <base/process.h>
11 #include "mozilla/dom/ipc/IdType.h"
12 #include "mozilla/HashTable.h"
13 #include "mozilla/MozPromise.h"
18 class GeckoChildProcessHost
;
21 // Process types. When updating this enum, please make sure to update
22 // WebIDLProcType, ChromeUtils::RequestProcInfo and ProcTypeToWebIDL to
23 // mirror the changes.
25 // These must match the ones in ContentParent.h, and E10SUtils.jsm
34 // the rest matches GeckoProcessTypes.h
35 Browser
, // Default is named Browser here
44 #ifdef MOZ_ENABLE_FORKSERVER
48 // Unknown type of process
55 base::ProcessId tid
= 0;
56 // Thread name, if any.
61 uint64_t cpuKernel
= 0;
64 // Info on a DOM window.
69 documentTitle(u
""_ns
),
72 WindowInfo(uint64_t aOuterWindowId
, nsIURI
* aDocumentURI
,
73 nsAString
&& aDocumentTitle
, bool aIsProcessRoot
, bool aIsInProcess
)
74 : outerWindowId(aOuterWindowId
),
75 documentURI(aDocumentURI
),
76 documentTitle(std::move(aDocumentTitle
)),
77 isProcessRoot(aIsProcessRoot
),
78 isInProcess(aIsInProcess
) {}
80 // Internal window id.
81 const uint64_t outerWindowId
;
83 // URI of the document.
84 const nsCOMPtr
<nsIURI
> documentURI
;
86 // Title of the document.
87 const nsString documentTitle
;
89 // True if this is the toplevel window of the process.
90 // Note that this may be an iframe from another process.
91 const bool isProcessRoot
;
93 const bool isInProcess
;
98 base::ProcessId pid
= 0;
99 // Child Id as defined by Firefox when a child process is created.
100 dom::ContentParentId childId
;
105 // Process filename (without the path name).
108 int64_t residentSetSize
= 0;
109 // Unshared resident size in bytes.
110 int64_t residentUniqueSize
= 0;
112 uint64_t cpuUser
= 0;
113 // System time in ns.
114 uint64_t cpuKernel
= 0;
115 // Threads owned by this process.
116 CopyableTArray
<ThreadInfo
> threads
;
117 // DOM windows represented by this process.
118 CopyableTArray
<WindowInfo
> windows
;
121 typedef MozPromise
<mozilla::HashMap
<base::ProcessId
, ProcInfo
>, nsresult
, true>
125 * Data we need to request process info (e.g. CPU usage, memory usage)
126 * from the operating system and populate the resulting `ProcInfo`.
128 * Note that this structure contains a mix of:
129 * - low-level handles that we need to request low-level process info
130 * (`aChildTask` on macOS, `aPid` on other platforms); and
131 * - high-level data that we already acquired while looking for
132 * `aPid`/`aChildTask` and that we will need further down the road.
134 struct ProcInfoRequest
{
135 ProcInfoRequest(base::ProcessId aPid
, ProcType aProcessType
,
136 const nsACString
& aOrigin
, nsTArray
<WindowInfo
>&& aWindowInfo
,
137 uint32_t aChildId
= 0
140 mach_port_t aChildTask
= 0
144 processType(aProcessType
),
146 windowInfo(std::move(aWindowInfo
)),
150 childTask(aChildTask
)
154 const base::ProcessId pid
;
155 const ProcType processType
;
156 const nsCString origin
;
157 const nsTArray
<WindowInfo
> windowInfo
;
158 // If the process is a child, its child id, otherwise `0`.
159 const int32_t childId
;
161 const mach_port_t childTask
;
166 * Batch a request for low-level information on Gecko processes.
170 * Argument `aRequests` is a list of processes, along with high-level data
171 * we have already obtained on them and that we need to populate the
172 * resulting array of `ProcInfo`.
176 * This call succeeds (possibly with missing data, see below) unless we
177 * cannot allocate memory.
181 * - This call is always executed on a background thread.
182 * - This call does NOT wake up children processes.
183 * - This function is sometimes observably slow to resolve, in particular
186 * # Error-handling and race conditions
188 * Requesting low-level information on a process and its threads is inherently
189 * subject to race conditions. Typically, if a process or a thread is killed
190 * while we're preparing to fetch information, we can easily end up with
191 * system/lib calls that return failures.
193 * For this reason, this API assumes that errors when placing a system/lib call
194 * are likely and normal. When some information cannot be obtained, the API will
195 * simply skip over said information.
197 * Note that due to different choices by OSes, the exact information we skip may
198 * vary across platforms. For instance, under Unix, failing to access the
199 * threads of a process will cause us to skip all data on the process, while
200 * under Windows, process information will be returned without thread
203 RefPtr
<ProcInfoPromise
> GetProcInfo(nsTArray
<ProcInfoRequest
>&& aRequests
);
206 * Utility function: copy data from a `ProcInfo` and into either a
207 * `ParentProcInfoDictionary` or a `ChildProcInfoDictionary`.
209 template <typename T
>
210 nsresult
CopySysProcInfoToDOM(const ProcInfo
& source
, T
* dest
) {
212 dest
->mPid
= source
.pid
;
213 dest
->mFilename
.Assign(source
.filename
);
214 dest
->mResidentSetSize
= source
.residentSetSize
;
215 dest
->mResidentUniqueSize
= source
.residentUniqueSize
;
216 dest
->mCpuUser
= source
.cpuUser
;
217 dest
->mCpuKernel
= source
.cpuKernel
;
220 mozilla::dom::Sequence
<mozilla::dom::ThreadInfoDictionary
> threads
;
221 for (const ThreadInfo
& entry
: source
.threads
) {
222 mozilla::dom::ThreadInfoDictionary
* thread
=
223 threads
.AppendElement(fallible
);
224 if (NS_WARN_IF(!thread
)) {
225 return NS_ERROR_OUT_OF_MEMORY
;
227 thread
->mCpuUser
= entry
.cpuUser
;
228 thread
->mCpuKernel
= entry
.cpuKernel
;
229 thread
->mTid
= entry
.tid
;
230 thread
->mName
.Assign(entry
.name
);
232 dest
->mThreads
= std::move(threads
);
236 } // namespace mozilla