hle: kernel: Provide methods for tracking dangling kernel objects.

This commit is contained in:
bunnei 2021-06-28 14:38:14 -07:00
parent 29fb110049
commit 929994132a
4 changed files with 43 additions and 2 deletions

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/kernel.h"
namespace Kernel { namespace Kernel {
@ -11,4 +12,12 @@ KAutoObject* KAutoObject::Create(KAutoObject* obj) {
return obj; return obj;
} }
void KAutoObject::RegisterWithKernel() {
kernel.RegisterKernelObject(this);
}
void KAutoObject::UnregisterWithKernel() {
kernel.UnregisterKernelObject(this);
}
} // namespace Kernel } // namespace Kernel

View file

@ -85,8 +85,12 @@ private:
KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject);
public: public:
explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {} explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {
virtual ~KAutoObject() = default; RegisterWithKernel();
}
virtual ~KAutoObject() {
UnregisterWithKernel();
}
static KAutoObject* Create(KAutoObject* ptr); static KAutoObject* Create(KAutoObject* ptr);
@ -166,6 +170,10 @@ public:
} }
} }
private:
void RegisterWithKernel();
void UnregisterWithKernel();
protected: protected:
KernelCore& kernel; KernelCore& kernel;
std::string name; std::string name;

View file

@ -142,6 +142,13 @@ struct KernelCore::Impl {
// Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
next_host_thread_id = Core::Hardware::NUM_CPU_CORES; next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
// Track kernel objects that were not freed on shutdown
if (registered_objects.size()) {
LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!",
registered_objects.size());
registered_objects.clear();
}
} }
void InitializePhysicalCores() { void InitializePhysicalCores() {
@ -656,6 +663,7 @@ struct KernelCore::Impl {
/// the ConnectToPort SVC. /// the ConnectToPort SVC.
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
NamedPortTable named_ports; NamedPortTable named_ports;
std::unordered_set<KAutoObject*> registered_objects;
std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
std::vector<Kernel::PhysicalCore> cores; std::vector<Kernel::PhysicalCore> cores;
@ -852,6 +860,14 @@ KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
return &search->second(impl->system.ServiceManager(), impl->system); return &search->second(impl->system.ServiceManager(), impl->system);
} }
void KernelCore::RegisterKernelObject(KAutoObject* object) {
impl->registered_objects.insert(object);
}
void KernelCore::UnregisterKernelObject(KAutoObject* object) {
impl->registered_objects.erase(object);
}
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
return port != impl->named_ports.cend(); return port != impl->named_ports.cend();
} }

View file

@ -185,6 +185,14 @@ public:
/// Opens a port to a service previously registered with RegisterNamedService. /// Opens a port to a service previously registered with RegisterNamedService.
KClientPort* CreateNamedServicePort(std::string name); KClientPort* CreateNamedServicePort(std::string name);
/// Registers all kernel objects with the global emulation state, this is purely for tracking
/// leaks after emulation has been shutdown.
void RegisterKernelObject(KAutoObject* object);
/// Unregisters a kernel object previously registered with RegisterKernelObject when it was
/// destroyed during the current emulation session.
void UnregisterKernelObject(KAutoObject* object);
/// Determines whether or not the given port is a valid named port. /// Determines whether or not the given port is a valid named port.
bool IsValidNamedPort(NamedPortTable::const_iterator port) const; bool IsValidNamedPort(NamedPortTable::const_iterator port) const;