Bug 1632794 - Expose full remoteType through ChromeUtils.requestProcInfo;

The current `type` field doesn't expose all information such as the origin. Let's fix this.

Differential Revision: https://phabricator.services.mozilla.com/D72616
This commit is contained in:
David Teller 2020-05-06 20:11:55 +00:00
parent 40aaada87c
commit e67467e850
7 changed files with 88 additions and 20 deletions

View File

@ -741,9 +741,12 @@ static WebIDLProcType ProcTypeToWebIDL(mozilla::ProcType aType) {
switch (aType) {
PROCTYPE_TO_WEBIDL_CASE(Web, Web);
PROCTYPE_TO_WEBIDL_CASE(WebIsolated, WebIsolated);
PROCTYPE_TO_WEBIDL_CASE(File, File);
PROCTYPE_TO_WEBIDL_CASE(Extension, Extension);
PROCTYPE_TO_WEBIDL_CASE(PrivilegedAbout, Privilegedabout);
PROCTYPE_TO_WEBIDL_CASE(PrivilegedMozilla, Privilegedmozilla);
PROCTYPE_TO_WEBIDL_CASE(WebCOOPCOEP, WithCoopCoep);
PROCTYPE_TO_WEBIDL_CASE(WebLargeAllocation, WebLargeAllocation);
PROCTYPE_TO_WEBIDL_CASE(Browser, Browser);
PROCTYPE_TO_WEBIDL_CASE(Plugin, Plugin);
@ -789,7 +792,8 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
global->EventTargetFor(TaskCategory::Performance);
// Getting the parent proc info
mozilla::GetProcInfo(parentPid, 0, mozilla::ProcType::Browser)
mozilla::GetProcInfo(parentPid, 0, mozilla::ProcType::Browser,
NS_LITERAL_STRING(""))
->Then(
target, __func__,
[target, domPromise, parentPid](ProcInfo aParentInfo) {
@ -803,7 +807,7 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
if (!aGeckoProcess->GetChildProcessHandle()) {
return;
}
nsAutoString origin;
base::ProcessId childPid =
base::GetProcId(aGeckoProcess->GetChildProcessHandle());
int32_t childId = 0;
@ -823,22 +827,51 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
if (!contentParent) {
return;
}
// Converting the Content Type into a ProcType
nsAutoString processType;
processType.Assign(contentParent->GetRemoteType());
if (IsWebRemoteType(processType)) {
// Converting the remoteType into a ProcType.
// Ideally, the remoteType should be strongly typed
// upstream, this would make the conversion less brittle.
nsAutoString remoteType(contentParent->GetRemoteType());
if (StringBeginsWith(
remoteType,
NS_LITERAL_STRING(FISSION_WEB_REMOTE_TYPE))) {
// WARNING: Do not change the order, as
// `DEFAULT_REMOTE_TYPE` is a prefix of
// `FISSION_WEB_REMOTE_TYPE`.
type = mozilla::ProcType::WebIsolated;
} else if (StringBeginsWith(
remoteType,
NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE))) {
type = mozilla::ProcType::Web;
} else if (processType.EqualsLiteral(FILE_REMOTE_TYPE)) {
} else if (remoteType.EqualsLiteral(FILE_REMOTE_TYPE)) {
type = mozilla::ProcType::File;
} else if (processType.EqualsLiteral(
} else if (remoteType.EqualsLiteral(
EXTENSION_REMOTE_TYPE)) {
type = mozilla::ProcType::Extension;
} else if (processType.EqualsLiteral(
} else if (remoteType.EqualsLiteral(
PRIVILEGEDABOUT_REMOTE_TYPE)) {
type = mozilla::ProcType::PrivilegedAbout;
} else if (processType.EqualsLiteral(
} else if (remoteType.EqualsLiteral(
PRIVILEGEDMOZILLA_REMOTE_TYPE)) {
type = mozilla::ProcType::PrivilegedMozilla;
} else if (StringBeginsWith(
remoteType,
NS_LITERAL_STRING(
WITH_COOP_COEP_REMOTE_TYPE_PREFIX))) {
type = mozilla::ProcType::WebCOOPCOEP;
} else if (remoteType.EqualsLiteral(
LARGE_ALLOCATION_REMOTE_TYPE)) {
type = mozilla::ProcType::WebLargeAllocation;
} else {
MOZ_CRASH("Unknown remoteType");
}
// By convention, everything after '=' is the origin.
nsAString::const_iterator cursor;
nsAString::const_iterator end;
remoteType.BeginReading(cursor);
remoteType.EndReading(end);
if (FindCharInReadable(u'=', cursor, end)) {
origin = Substring(++cursor, end);
}
childId = contentParent->ChildID();
break;
@ -879,10 +912,10 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
promises.AppendElement(
#ifdef XP_MACOSX
mozilla::GetProcInfo(childPid, childId, type,
mozilla::GetProcInfo(childPid, childId, type, origin,
aGeckoProcess->GetChildTask())
#else
mozilla::GetProcInfo(childPid, childId, type)
mozilla::GetProcInfo(childPid, childId, type, origin)
#endif
);
});
@ -928,6 +961,7 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
// Basic info.
childProcInfo->mChildID = info.childId;
childProcInfo->mType = ProcTypeToWebIDL(info.type);
childProcInfo->mOrigin = info.origin;
childProcInfo->mPid = info.pid;
childProcInfo->mFilename.Assign(info.filename);
childProcInfo->mVirtualMemorySize = info.virtualMemorySize;

View File

@ -498,10 +498,13 @@ partial namespace ChromeUtils {
*/
enum WebIDLProcType {
"web",
"webIsolated",
"file",
"extension",
"privilegedabout",
"privilegedmozilla",
"webLargeAllocation",
"withCoopCoep",
"browser",
"plugin",
"ipdlUnitTest",
@ -541,6 +544,7 @@ dictionary ChildProcInfoDictionary {
sequence<ThreadInfoDictionary> threads = [];
// Firefox info
unsigned long long ChildID = 0;
DOMString origin = "";
WebIDLProcType type = "web";
};

View File

@ -22,10 +22,13 @@ class GeckoChildProcessHost;
enum class ProcType {
// These must match the ones in ContentParent.h, and E10SUtils.jsm
Web,
WebIsolated,
File,
Extension,
PrivilegedAbout,
PrivilegedMozilla,
WebLargeAllocation,
WebCOOPCOEP,
// the rest matches GeckoProcessTypes.h
Browser, // Default is named Browser here
Plugin,
@ -62,6 +65,8 @@ struct ProcInfo {
dom::ContentParentId childId;
// Process type
ProcType type;
// Origin, if any
nsString origin;
// Process filename (without the path name).
nsString filename;
// VMS in bytes.
@ -86,11 +91,13 @@ typedef MozPromise<ProcInfo, nsresult, true> ProcInfoPromise;
*/
#ifdef XP_MACOSX
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type,
const ProcType& processType,
const nsAString& origin,
mach_port_t aChildTask = MACH_PORT_NULL);
#else
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type);
const ProcType& processType,
const nsAString& origin);
#endif
} // namespace mozilla

View File

@ -20,7 +20,7 @@
namespace mozilla {
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const ProcType& type,
mach_port_t aChildTask) {
const nsAString& origin, mach_port_t aChildTask) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);
@ -32,11 +32,15 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const
return promise;
}
auto ResolveGetProcinfo = [holder = std::move(holder), pid, type, childId, aChildTask]() {
// Ensure that the string is still alive when `ResolveGetProcInfo` is called.
nsString originCopy(origin);
auto ResolveGetProcinfo = [holder = std::move(holder), pid, type,
originCopy = std::move(originCopy), childId, aChildTask]() {
ProcInfo info;
info.pid = pid;
info.childId = childId;
info.type = type;
info.origin = originCopy;
struct proc_bsdinfo proc;
if ((unsigned long)proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE) <
PROC_PIDTBSDINFO_SIZE) {

View File

@ -208,7 +208,8 @@ class ThreadInfoReader final : public StatReader {
};
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type) {
const ProcType& type,
const nsAString& origin) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);
nsresult rv = NS_OK;
@ -220,8 +221,11 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
return promise;
}
// Ensure that the string is still alive when the runnable is called.
nsString originCopy(origin);
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(
__func__, [holder = std::move(holder), pid, type, childId]() {
__func__, [holder = std::move(holder), pid, type,
originCopy = std::move(originCopy), childId]() {
// opening the stat file and reading its content
StatReader reader(pid);
ProcInfo info;
@ -233,6 +237,7 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
// Extra info
info.childId = childId;
info.type = type;
info.origin = originCopy;
// Let's look at the threads
nsCString taskPath;

View File

@ -8,6 +8,7 @@ const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const MAC = AppConstants.platform == "macosx";
const isFissionEnabled = Services.prefs.getBoolPref("fission.autostart");
add_task(async function test_proc_info() {
waitForExplicitFinish();
@ -42,6 +43,13 @@ add_task(async function test_proc_info() {
"unknown",
"Child proc type should be known"
);
if (childProc.type == "webIsolated") {
Assert.notEqual(
childProc.origin || "",
"",
"Child process should have an origin"
);
}
for (var y = 0; y < childProc.threads.length; y++) {
cpuThreads += childProc.threads[y].cpuUser;

View File

@ -73,7 +73,8 @@ void AppendThreads(ProcInfo* info) {
}
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type) {
const ProcType& type,
const nsAString& origin) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);
@ -86,8 +87,12 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
return promise;
}
// Ensure that the string is still alive when `ResolveGetProcInfo` is called.
nsString originCopy(origin);
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(
__func__, [holder = std::move(holder), pid, type, childId]() -> void {
__func__,
[holder = std::move(holder), originCopy = std::move(originCopy), pid,
type, childId]() -> void {
nsAutoHandle handle(OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
@ -118,6 +123,7 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
info.pid = pid;
info.childId = childId;
info.type = type;
info.origin = originCopy;
info.filename.Assign(filename);
info.cpuKernel = ToNanoSeconds(kernelTime);
info.cpuUser = ToNanoSeconds(userTime);