mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-29 14:05:17 -04:00
kern: add kernel object debug
This commit is contained in:
parent
0acd79c8c2
commit
1a6e003a5d
16 changed files with 341 additions and 15 deletions
|
@ -112,6 +112,7 @@ namespace ams::kern::arch::arm64 {
|
|||
L1PageTableEntry *Finalize();
|
||||
|
||||
void Dump(uintptr_t start, size_t size) const;
|
||||
size_t CountPageTables() const;
|
||||
|
||||
bool BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const;
|
||||
bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;
|
||||
|
|
|
@ -232,14 +232,18 @@ namespace ams::kern::arch::arm64 {
|
|||
return this->page_table.UnmapPhysicalMemoryUnsafe(address, size);
|
||||
}
|
||||
|
||||
void DumpTable() const {
|
||||
return this->page_table.DumpTable();
|
||||
}
|
||||
|
||||
void DumpMemoryBlocks() const {
|
||||
return this->page_table.DumpMemoryBlocks();
|
||||
}
|
||||
|
||||
void DumpPageTable() const {
|
||||
return this->page_table.DumpPageTable();
|
||||
}
|
||||
|
||||
size_t CountPageTables() const {
|
||||
return this->page_table.CountPageTables();
|
||||
}
|
||||
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
|
||||
return this->page_table.GetPhysicalAddress(out, address);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ namespace ams::kern::arch::arm64 {
|
|||
}
|
||||
|
||||
constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return this->ttbr0_identity[core_id]; }
|
||||
|
||||
size_t CountPageTables() const {
|
||||
return this->page_table.CountPageTables();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace ams::kern::KDumpObject {
|
|||
void DumpThreadCallStack();
|
||||
void DumpThreadCallStack(u64 thread_id);
|
||||
|
||||
void DumpKernelObject();
|
||||
|
||||
void DumpHandle();
|
||||
void DumpHandle(u64 process_id);
|
||||
|
||||
|
|
|
@ -90,6 +90,8 @@ namespace ams::kern {
|
|||
|
||||
size_t GetFreeSize() const { return this->heap.GetFreeSize(); }
|
||||
|
||||
void DumpFreeList() const { return this->heap.DumpFreeList(); }
|
||||
|
||||
constexpr size_t GetPageOffset(KVirtualAddress address) const { return this->heap.GetPageOffset(address); }
|
||||
constexpr size_t GetPageOffsetToEnd(KVirtualAddress address) const { return this->heap.GetPageOffsetToEnd(address); }
|
||||
|
||||
|
@ -247,12 +249,15 @@ namespace ams::kern {
|
|||
size_t GetFreeSize() {
|
||||
size_t total = 0;
|
||||
for (size_t i = 0; i < this->num_managers; i++) {
|
||||
KScopedLightLock lk(this->pool_locks[this->managers[i].GetPool()]);
|
||||
total += this->managers[i].GetFreeSize();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t GetFreeSize(Pool pool) {
|
||||
KScopedLightLock lk(this->pool_locks[pool]);
|
||||
|
||||
constexpr Direction GetSizeDirection = Direction_FromFront;
|
||||
size_t total = 0;
|
||||
for (auto *manager = this->GetFirstManager(pool, GetSizeDirection); manager != nullptr; manager = this->GetNextManager(manager, GetSizeDirection)) {
|
||||
|
@ -260,6 +265,15 @@ namespace ams::kern {
|
|||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void DumpFreeList(Pool pool) {
|
||||
KScopedLightLock lk(this->pool_locks[pool]);
|
||||
|
||||
constexpr Direction DumpDirection = Direction_FromFront;
|
||||
for (auto *manager = this->GetFirstManager(pool, DumpDirection); manager != nullptr; manager = this->GetNextManager(manager, DumpDirection)) {
|
||||
manager->DumpFreeList();
|
||||
}
|
||||
}
|
||||
public:
|
||||
static size_t CalculateManagementOverheadSize(size_t region_size) {
|
||||
return Impl::CalculateManagementOverheadSize(region_size);
|
||||
|
|
|
@ -147,6 +147,7 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; }
|
||||
void DumpFreeList() const;
|
||||
|
||||
void UpdateUsedSize() {
|
||||
this->used_size = this->heap_size - (this->GetNumFreePages() * PageSize);
|
||||
|
|
|
@ -382,9 +382,9 @@ namespace ams::kern {
|
|||
Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
||||
Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
||||
|
||||
void DumpTable() const {
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
this->GetImpl().Dump(GetInteger(this->address_space_start), this->address_space_end - this->address_space_start);
|
||||
void DumpMemoryBlocksLocked() const {
|
||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||
this->memory_block_manager.DumpBlocks();
|
||||
}
|
||||
|
||||
void DumpMemoryBlocks() const {
|
||||
|
@ -392,9 +392,14 @@ namespace ams::kern {
|
|||
this->DumpMemoryBlocksLocked();
|
||||
}
|
||||
|
||||
void DumpMemoryBlocksLocked() const {
|
||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||
this->memory_block_manager.DumpBlocks();
|
||||
void DumpPageTable() const {
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
this->GetImpl().Dump(GetInteger(this->address_space_start), this->address_space_end - this->address_space_start);
|
||||
}
|
||||
|
||||
size_t CountPageTables() const {
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
return this->GetImpl().CountPageTables();
|
||||
}
|
||||
public:
|
||||
KProcessAddress GetAddressSpaceStart() const { return this->address_space_start; }
|
||||
|
|
|
@ -305,6 +305,11 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
|
||||
const KDynamicPageManager &GetDynamicPageManager() const { return this->dynamic_page_manager; }
|
||||
const KMemoryBlockSlabManager &GetMemoryBlockSlabManager() const { return this->memory_block_slab_manager; }
|
||||
const KBlockInfoManager &GetBlockInfoManager() const { return this->block_info_manager; }
|
||||
const KPageTableManager &GetPageTableManager() const { return this->page_table_manager; }
|
||||
|
||||
constexpr KThread *GetRunningThread(s32 core) const { return this->running_threads[core]; }
|
||||
constexpr u64 GetRunningThreadIdleCount(s32 core) const { return this->running_thread_idle_counts[core]; }
|
||||
|
||||
|
|
|
@ -140,7 +140,21 @@ namespace ams::kern {
|
|||
|
||||
void *obj = this->GetImpl()->Allocate();
|
||||
|
||||
/* TODO: under some debug define, track the peak for statistics, as N does? */
|
||||
/* Track the allocated peak. */
|
||||
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
|
||||
if (AMS_LIKELY(obj != nullptr)) {
|
||||
static_assert(std::atomic_ref<uintptr_t>::is_always_lock_free);
|
||||
std::atomic_ref<uintptr_t> peak_ref(this->peak);
|
||||
|
||||
const uintptr_t alloc_peak = reinterpret_cast<uintptr_t>(obj) + this->GetObjectSize();
|
||||
uintptr_t cur_peak = this->peak;
|
||||
do {
|
||||
if (alloc_peak <= cur_peak) {
|
||||
break;
|
||||
}
|
||||
} while (!peak_ref.compare_exchange_strong(cur_peak, alloc_peak));
|
||||
}
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -165,6 +179,29 @@ namespace ams::kern {
|
|||
uintptr_t GetSlabHeapAddress() const {
|
||||
return this->start;
|
||||
}
|
||||
|
||||
size_t GetNumRemaining() const {
|
||||
size_t remaining = 0;
|
||||
|
||||
/* Only calculate the number of remaining objects under debug configuration. */
|
||||
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
|
||||
while (true) {
|
||||
auto *cur = this->GetImpl()->GetHead();
|
||||
remaining = 0;
|
||||
|
||||
while (this->Contains(reinterpret_cast<uintptr_t>(cur))) {
|
||||
++remaining;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
if (cur == nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return remaining;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -48,6 +48,8 @@ namespace ams::kern {
|
|||
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
||||
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
||||
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
||||
|
||||
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
|
||||
};
|
||||
|
||||
template<typename Derived, typename Base>
|
||||
|
@ -116,6 +118,8 @@ namespace ams::kern {
|
|||
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
||||
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
||||
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
||||
|
||||
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue