Fix Killing Guest Processes in `KThread::Kill` and fix TID/PID naming

This commit mainly fixes the problem with process leakage before where the guest process wouldn't be killed. In addition, it clears up the problem with naming differences with PID/TID where purely PID was used before but that term is generally used to refer to the PGID. So, `KProcess` has a `pid` member but `KThread` has a `tid` member.
This commit is contained in:
◱ PixelyIon 2020-04-20 01:26:49 +05:30 committed by ◱ PixelyIon
parent 4637b4ac97
commit a0b9a635ca
5 changed files with 19 additions and 18 deletions

View File

@ -231,7 +231,7 @@ namespace skyline::kernel::svc {
}
auto thread = state.process->CreateThread(entryAddress, entryArgument, stackTop, priority);
state.logger->Debug("svcCreateThread: Created thread with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, PID: {})", thread->handle, entryAddress, entryArgument, stackTop, priority, thread->pid);
state.logger->Debug("svcCreateThread: Created thread with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, PID: {})", thread->handle, entryAddress, entryArgument, stackTop, priority, thread->tid);
state.ctx->registers.w1 = thread->handle;
state.ctx->registers.w0 = constant::status::Success;
@ -241,7 +241,7 @@ namespace skyline::kernel::svc {
auto handle = state.ctx->registers.w0;
try {
auto thread = state.process->GetHandle<type::KThread>(handle);
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->pid);
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid);
thread->Start();
state.ctx->registers.w0 = constant::status::Success;
} catch (const std::exception &) {
@ -251,8 +251,8 @@ namespace skyline::kernel::svc {
}
void ExitThread(DeviceState &state) {
state.logger->Debug("svcExitThread: Exiting current thread: {}", state.thread->pid);
state.os->KillThread(state.thread->pid);
state.logger->Debug("svcExitThread: Exiting current thread: {}", state.thread->tid);
state.os->KillThread(state.thread->tid);
}
void SleepThread(DeviceState &state) {
@ -610,9 +610,9 @@ namespace skyline::kernel::svc {
pid_t pid{};
if (handle != threadSelf)
pid = state.process->GetHandle<type::KThread>(handle)->pid;
pid = state.process->GetHandle<type::KThread>(handle)->tid;
else
pid = state.thread->pid;
pid = state.thread->tid;
state.logger->Debug("svcGetThreadId: Handle: 0x{:X}, PID: {}", handle, pid);

View File

@ -111,7 +111,7 @@ namespace skyline {
};
KHandle handleIndex = constant::BaseHandleIndex; //!< This is used to keep track of what to map as an handle
pid_t pid; //!< The PID of the main thread
pid_t pid; //!< The PID of the process or TGID of the threads
int memFd; //!< The file descriptor to the memory of the process
std::unordered_map<KHandle, std::shared_ptr<KObject>> handles; //!< A mapping from a handle_t to it's corresponding KObject which is the actual underlying object
std::unordered_map<pid_t, std::shared_ptr<KThread>> threads; //!< A mapping from a PID to it's corresponding KThread object

View File

@ -7,8 +7,8 @@
#include "KProcess.h"
namespace skyline::kernel::type {
KThread::KThread(const DeviceState &state, KHandle handle, pid_t selfPid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory)
: handle(handle), pid(selfPid), entryPoint(entryPoint), entryArg(entryArg), stackTop(stackTop), tls(tls), priority(priority), parent(parent), ctxMemory(tlsMemory), KSyncObject(state, KType::KThread) {
KThread::KThread(const DeviceState &state, KHandle handle, pid_t selfTid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory)
: handle(handle), tid(selfTid), entryPoint(entryPoint), entryArg(entryArg), stackTop(stackTop), tls(tls), priority(priority), parent(parent), ctxMemory(tlsMemory), KSyncObject(state, KType::KThread) {
UpdatePriority(priority);
}
@ -18,11 +18,11 @@ namespace skyline::kernel::type {
void KThread::Start() {
if (status == Status::Created) {
if (pid == parent->pid)
if (tid == parent->pid)
parent->status = KProcess::Status::Started;
status = Status::Running;
state.nce->StartThread(entryArg, handle, parent->threads.at(pid));
state.nce->StartThread(entryArg, handle, parent->threads.at(tid));
}
}
@ -30,6 +30,7 @@ namespace skyline::kernel::type {
if (status != Status::Dead) {
status = Status::Dead;
Signal();
tgkill(parent->pid, tid, SIGKILL);
}
}
@ -38,7 +39,7 @@ namespace skyline::kernel::type {
auto linuxPriority =
static_cast<int8_t>(constant::AndroidPriority.first + ((static_cast<float>(constant::AndroidPriority.second - constant::AndroidPriority.first) / static_cast<float>(constant::SwitchPriority.second - constant::SwitchPriority.first)) * (static_cast<float>(priority) - constant::SwitchPriority.first))); // Resize range SwitchPriority (Nintendo Priority) to AndroidPriority (Android Priority)
if (setpriority(PRIO_PROCESS, static_cast<id_t>(pid), linuxPriority) == -1)
throw exception("Couldn't set process priority to {} for PID: {}", linuxPriority, pid);
if (setpriority(PRIO_PROCESS, static_cast<id_t>(tid), linuxPriority) == -1)
throw exception("Couldn't set process priority to {} for PID: {}", linuxPriority, tid);
}
}

View File

@ -25,7 +25,7 @@ namespace skyline::kernel::type {
std::atomic<bool> cancelSync{false}; //!< This is to flag to a thread to cancel a synchronization call it currently is in
std::shared_ptr<type::KSharedMemory> ctxMemory; //!< The KSharedMemory of the shared memory allocated by the guest process TLS
KHandle handle; // The handle of the object in the handle table
pid_t pid; //!< The PID of the current thread (As in kernel PID and not PGID [In short, Linux implements threads as processes that share a lot of stuff at the kernel level])
pid_t tid; //!< The TID of the current thread
u64 stackTop; //!< The top of the stack (Where it starts growing downwards from)
u64 tls; //!< The address of TLS (Thread Local Storage) slot assigned to the current thread
u8 priority; //!< The priority of a thread in Nintendo format
@ -33,7 +33,7 @@ namespace skyline::kernel::type {
/**
* @param state The state of the device
* @param handle The handle of the current thread
* @param selfPid The PID of this thread
* @param selfTid The TID of this thread
* @param entryPoint The address to start execution at
* @param entryArg An argument to pass to the process on entry
* @param stackTop The top of the stack
@ -42,7 +42,7 @@ namespace skyline::kernel::type {
* @param parent The parent process of this thread
* @param tlsMemory The KSharedMemory object for TLS memory allocated by the guest process
*/
KThread(const DeviceState &state, KHandle handle, pid_t selfPid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory);
KThread(const DeviceState &state, KHandle handle, pid_t selfTid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory);
/**
* @brief Kills the thread and deallocates the memory allocated for stack.

View File

@ -155,8 +155,8 @@ namespace skyline {
ctx->registers.x1 = handle;
ctx->state = ThreadState::WaitRun;
state.logger->Debug("Starting kernel thread for guest thread: {}", thread->pid);
threadMap[thread->pid] = std::make_shared<std::thread>(&NCE::KernelThread, this, thread->pid);
state.logger->Debug("Starting kernel thread for guest thread: {}", thread->tid);
threadMap[thread->tid] = std::make_shared<std::thread>(&NCE::KernelThread, this, thread->tid);
}
void NCE::ThreadTrace(u16 numHist, ThreadContext *ctx) {