summaryrefslogtreecommitdiff
path: root/src/core/hle/service/pm
diff options
context:
space:
mode:
authorGravatar Liam2024-01-02 17:12:16 -0500
committerGravatar Liam2024-01-12 18:31:33 -0500
commitf90a022d3a20c86399f49a8154847b73bc1b8fd3 (patch)
tree672214411189aaf408febc5aa9cc01e45aed5f5f /src/core/hle/service/pm
parentkernel: fix page leak on process termination (diff)
downloadyuzu-f90a022d3a20c86399f49a8154847b73bc1b8fd3.tar.gz
yuzu-f90a022d3a20c86399f49a8154847b73bc1b8fd3.tar.xz
yuzu-f90a022d3a20c86399f49a8154847b73bc1b8fd3.zip
kernel: fix debugger and process list lifetime
Diffstat (limited to 'src/core/hle/service/pm')
-rw-r--r--src/core/hle/service/pm/pm.cpp85
1 files changed, 37 insertions, 48 deletions
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp
index d92499f05..b52468e41 100644
--- a/src/core/hle/service/pm/pm.cpp
+++ b/src/core/hle/service/pm/pm.cpp
@@ -22,27 +22,26 @@ constexpr Result ResultProcessNotFound{ErrorModule::PM, 1};
22 22
23constexpr u64 NO_PROCESS_FOUND_PID{0}; 23constexpr u64 NO_PROCESS_FOUND_PID{0};
24 24
25std::optional<Kernel::KProcess*> SearchProcessList( 25using ProcessList = std::list<Kernel::KScopedAutoObject<Kernel::KProcess>>;
26 const std::vector<Kernel::KProcess*>& process_list, 26
27 std::function<bool(Kernel::KProcess*)> predicate) { 27template <typename F>
28Kernel::KScopedAutoObject<Kernel::KProcess> SearchProcessList(ProcessList& process_list,
29 F&& predicate) {
28 const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); 30 const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
29 31
30 if (iter == process_list.end()) { 32 if (iter == process_list.end()) {
31 return std::nullopt; 33 return nullptr;
32 } 34 }
33 35
34 return *iter; 36 return iter->GetPointerUnsafe();
35} 37}
36 38
37void GetApplicationPidGeneric(HLERequestContext& ctx, 39void GetApplicationPidGeneric(HLERequestContext& ctx, ProcessList& process_list) {
38 const std::vector<Kernel::KProcess*>& process_list) { 40 auto process = SearchProcessList(process_list, [](auto& p) { return p->IsApplication(); });
39 const auto process = SearchProcessList(process_list, [](const auto& proc) {
40 return proc->GetProcessId() == Kernel::KProcess::ProcessIdMin;
41 });
42 41
43 IPC::ResponseBuilder rb{ctx, 4}; 42 IPC::ResponseBuilder rb{ctx, 4};
44 rb.Push(ResultSuccess); 43 rb.Push(ResultSuccess);
45 rb.Push(process.has_value() ? (*process)->GetProcessId() : NO_PROCESS_FOUND_PID); 44 rb.Push(process.IsNull() ? NO_PROCESS_FOUND_PID : process->GetProcessId());
46} 45}
47 46
48} // Anonymous namespace 47} // Anonymous namespace
@@ -80,8 +79,7 @@ private:
80 79
81class DebugMonitor final : public ServiceFramework<DebugMonitor> { 80class DebugMonitor final : public ServiceFramework<DebugMonitor> {
82public: 81public:
83 explicit DebugMonitor(Core::System& system_) 82 explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "pm:dmnt"} {
84 : ServiceFramework{system_, "pm:dmnt"}, kernel{system_.Kernel()} {
85 // clang-format off 83 // clang-format off
86 static const FunctionInfo functions[] = { 84 static const FunctionInfo functions[] = {
87 {0, nullptr, "GetJitDebugProcessIdList"}, 85 {0, nullptr, "GetJitDebugProcessIdList"},
@@ -106,12 +104,11 @@ private:
106 104
107 LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); 105 LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id);
108 106
109 const auto process = 107 auto list = kernel.GetProcessList();
110 SearchProcessList(kernel.GetProcessList(), [program_id](const auto& proc) { 108 auto process = SearchProcessList(
111 return proc->GetProgramId() == program_id; 109 list, [program_id](auto& p) { return p->GetProgramId() == program_id; });
112 });
113 110
114 if (!process.has_value()) { 111 if (process.IsNull()) {
115 IPC::ResponseBuilder rb{ctx, 2}; 112 IPC::ResponseBuilder rb{ctx, 2};
116 rb.Push(ResultProcessNotFound); 113 rb.Push(ResultProcessNotFound);
117 return; 114 return;
@@ -119,12 +116,13 @@ private:
119 116
120 IPC::ResponseBuilder rb{ctx, 4}; 117 IPC::ResponseBuilder rb{ctx, 4};
121 rb.Push(ResultSuccess); 118 rb.Push(ResultSuccess);
122 rb.Push((*process)->GetProcessId()); 119 rb.Push(process->GetProcessId());
123 } 120 }
124 121
125 void GetApplicationProcessId(HLERequestContext& ctx) { 122 void GetApplicationProcessId(HLERequestContext& ctx) {
126 LOG_DEBUG(Service_PM, "called"); 123 LOG_DEBUG(Service_PM, "called");
127 GetApplicationPidGeneric(ctx, kernel.GetProcessList()); 124 auto list = kernel.GetProcessList();
125 GetApplicationPidGeneric(ctx, list);
128 } 126 }
129 127
130 void AtmosphereGetProcessInfo(HLERequestContext& ctx) { 128 void AtmosphereGetProcessInfo(HLERequestContext& ctx) {
@@ -135,11 +133,10 @@ private:
135 133
136 LOG_WARNING(Service_PM, "(Partial Implementation) called, pid={:016X}", pid); 134 LOG_WARNING(Service_PM, "(Partial Implementation) called, pid={:016X}", pid);
137 135
138 const auto process = SearchProcessList(kernel.GetProcessList(), [pid](const auto& proc) { 136 auto list = kernel.GetProcessList();
139 return proc->GetProcessId() == pid; 137 auto process = SearchProcessList(list, [pid](auto& p) { return p->GetProcessId() == pid; });
140 });
141 138
142 if (!process.has_value()) { 139 if (process.IsNull()) {
143 IPC::ResponseBuilder rb{ctx, 2}; 140 IPC::ResponseBuilder rb{ctx, 2};
144 rb.Push(ResultProcessNotFound); 141 rb.Push(ResultProcessNotFound);
145 return; 142 return;
@@ -159,7 +156,7 @@ private:
159 156
160 OverrideStatus override_status{}; 157 OverrideStatus override_status{};
161 ProgramLocation program_location{ 158 ProgramLocation program_location{
162 .program_id = (*process)->GetProgramId(), 159 .program_id = process->GetProgramId(),
163 .storage_id = 0, 160 .storage_id = 0,
164 }; 161 };
165 162
@@ -169,14 +166,11 @@ private:
169 rb.PushRaw(program_location); 166 rb.PushRaw(program_location);
170 rb.PushRaw(override_status); 167 rb.PushRaw(override_status);
171 } 168 }
172
173 const Kernel::KernelCore& kernel;
174}; 169};
175 170
176class Info final : public ServiceFramework<Info> { 171class Info final : public ServiceFramework<Info> {
177public: 172public:
178 explicit Info(Core::System& system_, const std::vector<Kernel::KProcess*>& process_list_) 173 explicit Info(Core::System& system_) : ServiceFramework{system_, "pm:info"} {
179 : ServiceFramework{system_, "pm:info"}, process_list{process_list_} {
180 static const FunctionInfo functions[] = { 174 static const FunctionInfo functions[] = {
181 {0, &Info::GetProgramId, "GetProgramId"}, 175 {0, &Info::GetProgramId, "GetProgramId"},
182 {65000, &Info::AtmosphereGetProcessId, "AtmosphereGetProcessId"}, 176 {65000, &Info::AtmosphereGetProcessId, "AtmosphereGetProcessId"},
@@ -193,11 +187,11 @@ private:
193 187
194 LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id); 188 LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id);
195 189
196 const auto process = SearchProcessList(process_list, [process_id](const auto& proc) { 190 auto list = kernel.GetProcessList();
197 return proc->GetProcessId() == process_id; 191 auto process = SearchProcessList(
198 }); 192 list, [process_id](auto& p) { return p->GetProcessId() == process_id; });
199 193
200 if (!process.has_value()) { 194 if (process.IsNull()) {
201 IPC::ResponseBuilder rb{ctx, 2}; 195 IPC::ResponseBuilder rb{ctx, 2};
202 rb.Push(ResultProcessNotFound); 196 rb.Push(ResultProcessNotFound);
203 return; 197 return;
@@ -205,7 +199,7 @@ private:
205 199
206 IPC::ResponseBuilder rb{ctx, 4}; 200 IPC::ResponseBuilder rb{ctx, 4};
207 rb.Push(ResultSuccess); 201 rb.Push(ResultSuccess);
208 rb.Push((*process)->GetProgramId()); 202 rb.Push(process->GetProgramId());
209 } 203 }
210 204
211 void AtmosphereGetProcessId(HLERequestContext& ctx) { 205 void AtmosphereGetProcessId(HLERequestContext& ctx) {
@@ -214,11 +208,11 @@ private:
214 208
215 LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id); 209 LOG_DEBUG(Service_PM, "called, program_id={:016X}", program_id);
216 210
217 const auto process = SearchProcessList(process_list, [program_id](const auto& proc) { 211 auto list = system.Kernel().GetProcessList();
218 return proc->GetProgramId() == program_id; 212 auto process = SearchProcessList(
219 }); 213 list, [program_id](auto& p) { return p->GetProgramId() == program_id; });
220 214
221 if (!process.has_value()) { 215 if (process.IsNull()) {
222 IPC::ResponseBuilder rb{ctx, 2}; 216 IPC::ResponseBuilder rb{ctx, 2};
223 rb.Push(ResultProcessNotFound); 217 rb.Push(ResultProcessNotFound);
224 return; 218 return;
@@ -226,16 +220,13 @@ private:
226 220
227 IPC::ResponseBuilder rb{ctx, 4}; 221 IPC::ResponseBuilder rb{ctx, 4};
228 rb.Push(ResultSuccess); 222 rb.Push(ResultSuccess);
229 rb.Push((*process)->GetProcessId()); 223 rb.Push(process->GetProcessId());
230 } 224 }
231
232 const std::vector<Kernel::KProcess*>& process_list;
233}; 225};
234 226
235class Shell final : public ServiceFramework<Shell> { 227class Shell final : public ServiceFramework<Shell> {
236public: 228public:
237 explicit Shell(Core::System& system_) 229 explicit Shell(Core::System& system_) : ServiceFramework{system_, "pm:shell"} {
238 : ServiceFramework{system_, "pm:shell"}, kernel{system_.Kernel()} {
239 // clang-format off 230 // clang-format off
240 static const FunctionInfo functions[] = { 231 static const FunctionInfo functions[] = {
241 {0, nullptr, "LaunchProgram"}, 232 {0, nullptr, "LaunchProgram"},
@@ -257,10 +248,9 @@ public:
257private: 248private:
258 void GetApplicationProcessIdForShell(HLERequestContext& ctx) { 249 void GetApplicationProcessIdForShell(HLERequestContext& ctx) {
259 LOG_DEBUG(Service_PM, "called"); 250 LOG_DEBUG(Service_PM, "called");
260 GetApplicationPidGeneric(ctx, kernel.GetProcessList()); 251 auto list = kernel.GetProcessList();
252 GetApplicationPidGeneric(ctx, list);
261 } 253 }
262
263 const Kernel::KernelCore& kernel;
264}; 254};
265 255
266void LoopProcess(Core::System& system) { 256void LoopProcess(Core::System& system) {
@@ -268,8 +258,7 @@ void LoopProcess(Core::System& system) {
268 258
269 server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system)); 259 server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system));
270 server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system)); 260 server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system));
271 server_manager->RegisterNamedService( 261 server_manager->RegisterNamedService("pm:info", std::make_shared<Info>(system));
272 "pm:info", std::make_shared<Info>(system, system.Kernel().GetProcessList()));
273 server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system)); 262 server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system));
274 ServerManager::RunServer(std::move(server_manager)); 263 ServerManager::RunServer(std::move(server_manager));
275} 264}