Bug 1529023 - Enable threads on macOS for GetProcInfo r=jld,mstange

To run task_for_pid() on child processes, we need the child task port for
security reasons. This port can be obtained via a Mach IPC exchange.

This is what GeckoChildProcessHost::GetChildTask() provides, so we use it
in cocoa's version of GetProcInfo()

Differential Revision: https://phabricator.services.mozilla.com/D25927

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tarek Ziadé 2019-06-07 19:56:51 +00:00
Родитель b4932e4709
Коммит b18ccf9c4e
9 изменённых файлов: 57 добавлений и 28 удалений

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

@ -30,6 +30,7 @@
#include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/net/SocketProcessHost.h"
#include "IOActivityMonitor.h"
#include "nsIOService.h"
#include "nsThreadUtils.h"
@ -719,14 +720,16 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
}
promises.AppendElement(mozilla::GetProcInfo(
(base::ProcessId)childPid, contentParent->ChildID(), type));
(base::ProcessId)childPid, contentParent->ChildID(), type,
contentParent->Process()));
}
// Getting the Socket Process
int32_t SocketPid = net::gIOService->SocketProcessPid();
if (SocketPid != 0) {
promises.AppendElement(mozilla::GetProcInfo(
(base::ProcessId)SocketPid, 0, mozilla::ProcType::Socket));
(base::ProcessId)SocketPid, 0, mozilla::ProcType::Socket,
net::gIOService->SocketProcess()));
}
// Getting the GPU and RDD processes on supported platforms
@ -734,16 +737,16 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
if (pm) {
base::ProcessId GpuPid = pm->GPUProcessPid();
if (GpuPid != -1) {
promises.AppendElement(
mozilla::GetProcInfo(GpuPid, 0, mozilla::ProcType::Gpu));
promises.AppendElement(mozilla::GetProcInfo(
GpuPid, 0, mozilla::ProcType::Gpu, pm->Process()));
}
}
RDDProcessManager* RDDPm = RDDProcessManager::Get();
if (RDDPm) {
base::ProcessId RDDPid = RDDPm->RDDProcessPid();
if (RDDPid != -1) {
promises.AppendElement(
mozilla::GetProcInfo(RDDPid, 0, mozilla::ProcType::Rdd));
promises.AppendElement(mozilla::GetProcInfo(
RDDPid, 0, mozilla::ProcType::Rdd, RDDPm->Process()));
}
}

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

@ -61,6 +61,9 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
// Returns whether or not a RDD process was ever launched.
bool AttemptedRDDProcess() const { return mNumProcessAttempts > 0; }
// Returns the RDD Process
RDDProcessHost* Process() { return mProcess; }
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();

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

@ -176,6 +176,9 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// Returns whether or not a GPU process was ever launched.
bool AttemptedGPUProcess() const { return mNumProcessAttempts > 0; }
// Returns the process host
GPUProcessHost* Process() { return mProcess; }
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();

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

@ -129,6 +129,8 @@ class nsIOService final : public nsIIOService,
void CallOrWaitForSocketProcess(const std::function<void()>& aFunc);
int32_t SocketProcessPid();
SocketProcessHost* SocketProcess() { return mSocketProcess; }
friend SocketProcessMemoryReporter;
RefPtr<MemoryReportingProcess> GetSocketProcessMemoryReporter();

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

@ -12,6 +12,10 @@
namespace mozilla {
namespace ipc {
class GeckoChildProcessHost;
}
// Process types
enum class ProcType {
// These must match the ones in ContentParent.h and E10SUtils.jsm
@ -72,8 +76,9 @@ typedef MozPromise<ProcInfo, nsresult, true> ProcInfoPromise;
* Depending on the platform, this call can be quite expensive and the
* promise may return after several ms.
*/
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type);
RefPtr<ProcInfoPromise> GetProcInfo(
base::ProcessId pid, int32_t childId, const ProcType& type,
ipc::GeckoChildProcessHost* childProcess = nullptr);
} // namespace mozilla
#endif // ProcInfo_h

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

@ -5,11 +5,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ProcInfo.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
namespace mozilla {
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type) {
const ProcType& type,
ipc::GeckoChildProcessHost* childProcess) {
// Not implemented on Android.
return nullptr;
}

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

@ -5,8 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ProcInfo.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Logging.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "nsNetCID.h"
#include <cstdio>
@ -19,7 +19,8 @@
namespace mozilla {
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const ProcType& type) {
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const ProcType& type,
ipc::GeckoChildProcessHost* childProcess) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);
@ -31,7 +32,12 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const
return promise;
}
auto ResolveGetProcinfo = [holder = std::move(holder), pid, type, childId]() {
mach_port_t task = MACH_PORT_NULL;
if (childProcess && childProcess->GetChildTask() != MACH_PORT_NULL) {
task = childProcess->GetChildTask();
}
auto ResolveGetProcinfo = [holder = std::move(holder), pid, type, childId, task]() {
ProcInfo info;
info.pid = pid;
info.childId = childId;
@ -58,40 +64,42 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const
info.cpuKernel = pti.pti_total_system;
// Now getting threads info
mach_port_t task;
kern_return_t kret = task_for_pid(mach_task_self(), pid, &task);
if (kret != KERN_SUCCESS) {
// If we can't get threads detail, we just ignore that.
holder->Resolve(info, __func__);
return;
mach_port_t selectedTask;
// If we did not get a task from a child process, we use mach_task_self()
if (task == MACH_PORT_NULL) {
selectedTask = mach_task_self();
} else {
selectedTask = task;
}
// task_threads() gives us a snapshot of the process threads
// but those threads can go away. All the code below makes
// the assumption that thread_info() calls may fail, and
// these errors will be ignored.
thread_act_port_array_t threadList;
mach_msg_type_number_t threadCount;
kret = task_threads(task, &threadList, &threadCount);
kern_return_t kret = task_threads(selectedTask, &threadList, &threadCount);
if (kret != KERN_SUCCESS) {
holder->Resolve(info, __func__);
return;
}
mach_msg_type_number_t count;
for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
// Basic thread info.
mach_msg_type_number_t threadInfoCount = THREAD_EXTENDED_INFO_COUNT;
thread_extended_info_data_t threadInfoData;
kret = thread_info(threadList[i], THREAD_EXTENDED_INFO, (thread_info_t)&threadInfoData,
&threadInfoCount);
count = THREAD_EXTENDED_INFO_COUNT;
kret =
thread_info(threadList[i], THREAD_EXTENDED_INFO, (thread_info_t)&threadInfoData, &count);
if (kret != KERN_SUCCESS) {
continue;
}
// Getting the thread id.
thread_identifier_info identifierInfo;
count = THREAD_IDENTIFIER_INFO_COUNT;
kret = thread_info(threadList[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifierInfo,
&threadInfoCount);
&count);
if (kret != KERN_SUCCESS) {
continue;
}
@ -114,5 +122,4 @@ RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId, const
}
return promise;
}
}

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

@ -7,6 +7,7 @@
#include "mozilla/ProcInfo.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Logging.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "nsAutoRef.h"
#include "nsLocalFile.h"
#include "nsNetCID.h"
@ -207,7 +208,8 @@ class ThreadInfoReader final : public StatReader {
};
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type) {
const ProcType& type,
ipc::GeckoChildProcessHost* childProcess) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);
nsresult rv = NS_OK;

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

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ProcInfo.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
@ -72,7 +73,8 @@ void AppendThreads(ProcInfo* info) {
}
RefPtr<ProcInfoPromise> GetProcInfo(base::ProcessId pid, int32_t childId,
const ProcType& type) {
const ProcType& type,
ipc::GeckoChildProcessHost* childProcess) {
auto holder = MakeUnique<MozPromiseHolder<ProcInfoPromise>>();
RefPtr<ProcInfoPromise> promise = holder->Ensure(__func__);