|
@@ -98,6 +98,30 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons
|
|
|
return list;
|
|
return list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+WaitTreeCallstack::WaitTreeCallstack(const Kernel::Thread& thread) : thread(thread) {}
|
|
|
|
|
+
|
|
|
|
|
+QString WaitTreeCallstack::GetText() const {
|
|
|
|
|
+ return tr("Call stack");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() const {
|
|
|
|
|
+ std::vector<std::unique_ptr<WaitTreeItem>> list;
|
|
|
|
|
+
|
|
|
|
|
+ constexpr size_t BaseRegister = 29;
|
|
|
|
|
+ u64 base_pointer = thread.context.cpu_registers[BaseRegister];
|
|
|
|
|
+
|
|
|
|
|
+ while (base_pointer != 0) {
|
|
|
|
|
+ u64 lr = Memory::Read64(base_pointer + sizeof(u64));
|
|
|
|
|
+ if (lr == 0)
|
|
|
|
|
+ break;
|
|
|
|
|
+ list.push_back(
|
|
|
|
|
+ std::make_unique<WaitTreeText>(tr("0x%1").arg(lr - sizeof(u32), 16, 16, QChar('0'))));
|
|
|
|
|
+ base_pointer = Memory::Read64(base_pointer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return list;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {}
|
|
WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {}
|
|
|
|
|
|
|
|
bool WaitTreeExpandableItem::IsExpandable() const {
|
|
bool WaitTreeExpandableItem::IsExpandable() const {
|
|
@@ -269,6 +293,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
|
|
|
thread.IsSleepingOnWaitAll()));
|
|
thread.IsSleepingOnWaitAll()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ list.push_back(std::make_unique<WaitTreeCallstack>(thread));
|
|
|
|
|
+
|
|
|
return list;
|
|
return list;
|
|
|
}
|
|
}
|
|
|
|
|
|