зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b4932e4709
Коммит
b18ccf9c4e
|
@ -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__);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче