ThreadStackWidget.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "ThreadStackWidget.h"
  7. #include <AK/ByteBuffer.h>
  8. #include <LibCore/Timer.h>
  9. #include <LibGUI/BoxLayout.h>
  10. #include <LibSymbolication/Symbolication.h>
  11. #include <LibThreading/BackgroundAction.h>
  12. ThreadStackWidget::ThreadStackWidget()
  13. {
  14. set_layout<GUI::VerticalBoxLayout>();
  15. layout()->set_margins(4);
  16. m_stack_editor = add<GUI::TextEditor>();
  17. m_stack_editor->set_mode(GUI::TextEditor::ReadOnly);
  18. m_stack_editor->set_text("Symbolicating...");
  19. }
  20. ThreadStackWidget::~ThreadStackWidget()
  21. {
  22. }
  23. void ThreadStackWidget::show_event(GUI::ShowEvent&)
  24. {
  25. refresh();
  26. if (!m_timer)
  27. m_timer = add<Core::Timer>(1000, [this] { refresh(); });
  28. }
  29. void ThreadStackWidget::hide_event(GUI::HideEvent&)
  30. {
  31. m_timer = nullptr;
  32. }
  33. void ThreadStackWidget::set_ids(pid_t pid, pid_t tid)
  34. {
  35. if (m_pid == pid && m_tid == tid)
  36. return;
  37. m_pid = pid;
  38. m_tid = tid;
  39. }
  40. class CompletionEvent : public Core::CustomEvent {
  41. public:
  42. explicit CompletionEvent(Vector<Symbolication::Symbol> symbols)
  43. : Core::CustomEvent(0)
  44. , m_symbols(move(symbols))
  45. {
  46. }
  47. Vector<Symbolication::Symbol> const& symbols() const { return m_symbols; }
  48. private:
  49. Vector<Symbolication::Symbol> m_symbols;
  50. };
  51. void ThreadStackWidget::refresh()
  52. {
  53. Threading::BackgroundAction<Vector<Symbolication::Symbol>>::create(
  54. [pid = m_pid, tid = m_tid](auto&) {
  55. return Symbolication::symbolicate_thread(pid, tid);
  56. },
  57. [weak_this = make_weak_ptr()](auto result) {
  58. if (!weak_this)
  59. return;
  60. Core::EventLoop::main().post_event(const_cast<Core::Object&>(*weak_this), make<CompletionEvent>(move(result)));
  61. });
  62. }
  63. void ThreadStackWidget::custom_event(Core::CustomEvent& event)
  64. {
  65. auto& completion_event = verify_cast<CompletionEvent>(event);
  66. StringBuilder builder;
  67. for (auto& symbol : completion_event.symbols()) {
  68. builder.appendff("{:p}", symbol.address);
  69. if (!symbol.name.is_empty())
  70. builder.appendff(" {}", symbol.name);
  71. builder.append('\n');
  72. }
  73. if (m_stack_editor->text() != builder.string_view()) {
  74. m_stack_editor->set_text(builder.string_view());
  75. }
  76. }