Parcourir la source

SystemMonitor: Symbolicate process stacks in a background thread

Use a Threading::BackgroundAction to symbolicate stacks. This avoids
blocking the main thread and keeps the GUI running (mostly.)
Andreas Kling il y a 4 ans
Parent
commit
9676548800

+ 32 - 2
Userland/Applications/SystemMonitor/ThreadStackWidget.cpp

@@ -9,6 +9,7 @@
 #include <LibCore/Timer.h>
 #include <LibGUI/BoxLayout.h>
 #include <LibSymbolication/Symbolication.h>
+#include <LibThreading/BackgroundAction.h>
 
 ThreadStackWidget::ThreadStackWidget()
 {
@@ -16,6 +17,7 @@ ThreadStackWidget::ThreadStackWidget()
     layout()->set_margins({ 4, 4, 4, 4 });
     m_stack_editor = add<GUI::TextEditor>();
     m_stack_editor->set_mode(GUI::TextEditor::ReadOnly);
+    m_stack_editor->set_text("Symbolicating...");
 }
 
 ThreadStackWidget::~ThreadStackWidget()
@@ -42,13 +44,41 @@ void ThreadStackWidget::set_ids(pid_t pid, pid_t tid)
     m_tid = tid;
 }
 
+class CompletionEvent : public Core::CustomEvent {
+public:
+    explicit CompletionEvent(Vector<Symbolication::Symbol> symbols)
+        : Core::CustomEvent(0)
+        , m_symbols(move(symbols))
+    {
+    }
+
+    Vector<Symbolication::Symbol> const& symbols() const { return m_symbols; }
+
+private:
+    Vector<Symbolication::Symbol> m_symbols;
+};
+
 void ThreadStackWidget::refresh()
 {
-    auto symbols = Symbolication::symbolicate_thread(m_pid, m_tid);
+    Threading::BackgroundAction<Vector<Symbolication::Symbol>>::create(
+        [pid = m_pid, tid = m_tid] {
+            return Symbolication::symbolicate_thread(pid, tid);
+        },
+
+        [weak_this = make_weak_ptr()](auto result) {
+            if (!weak_this)
+                return;
+            Core::EventLoop::main().post_event(const_cast<Core::Object&>(*weak_this), make<CompletionEvent>(move(result)));
+        });
+}
+
+void ThreadStackWidget::custom_event(Core::CustomEvent& event)
+{
+    auto& completion_event = downcast<CompletionEvent>(event);
 
     StringBuilder builder;
 
-    for (auto& symbol : symbols) {
+    for (auto& symbol : completion_event.symbols()) {
         builder.appendff("{:p}", symbol.address);
         if (!symbol.name.is_empty())
             builder.appendff("  {}", symbol.name);

+ 1 - 0
Userland/Applications/SystemMonitor/ThreadStackWidget.h

@@ -22,6 +22,7 @@ private:
 
     virtual void show_event(GUI::ShowEvent&) override;
     virtual void hide_event(GUI::HideEvent&) override;
+    virtual void custom_event(Core::CustomEvent&) override;
 
     pid_t m_pid { -1 };
     pid_t m_tid { -1 };

+ 1 - 1
Userland/Applications/SystemMonitor/main.cpp

@@ -103,7 +103,7 @@ int main(int argc, char** argv)
         sched_setparam(0, &param);
     }
 
-    if (pledge("stdio proc recvfd sendfd rpath exec unix", nullptr) < 0) {
+    if (pledge("stdio thread proc recvfd sendfd rpath exec unix", nullptr) < 0) {
         perror("pledge");
         return 1;
     }