From c50393e06677e868d6a014d6ebe67057e8bdf9a7 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sat, 19 May 2018 16:52:49 -0500
Subject: [PATCH] Qt/WaitTree: Display the callstack for each thread in the
 wait tree widget.

---
 src/yuzu/debugger/wait_tree.cpp | 26 ++++++++++++++++++++++++++
 src/yuzu/debugger/wait_tree.h   | 11 +++++++++++
 2 files changed, 37 insertions(+)

diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 8b074db5a4..017bef13c5 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -98,6 +98,30 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons
     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) {}
 
 bool WaitTreeExpandableItem::IsExpandable() const {
@@ -269,6 +293,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
                                                             thread.IsSleepingOnWaitAll()));
     }
 
+    list.push_back(std::make_unique<WaitTreeCallstack>(thread));
+
     return list;
 }
 
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 300ba9ae46..10fc9e9680 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -73,6 +73,17 @@ private:
     Kernel::SharedPtr<Kernel::Thread> owner;
 };
 
+class WaitTreeCallstack : public WaitTreeExpandableItem {
+    Q_OBJECT
+public:
+    explicit WaitTreeCallstack(const Kernel::Thread& thread);
+    QString GetText() const override;
+    std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
+
+private:
+    const Kernel::Thread& thread;
+};
+
 class WaitTreeWaitObject : public WaitTreeExpandableItem {
     Q_OBJECT
 public:
-- 
GitLab