From 6e5b1f5819d3161156d2b919183f1e2b6ed40658 Mon Sep 17 00:00:00 2001 From: Itamar Date: Sun, 19 Feb 2023 21:48:45 +0200 Subject: [PATCH] HackStudio: Add progress bar to Debugger initialization During Debugger initialization, most of the time is spent creating DebugInfo objects for the libraries that the program has loaded. --- .../DevTools/HackStudio/Debugger/Debugger.cpp | 13 +++++++---- .../DevTools/HackStudio/Debugger/Debugger.h | 7 ++++-- .../DevTools/HackStudio/HackStudioWidget.cpp | 4 ++++ Userland/Libraries/LibDebug/DebugSession.cpp | 23 ++++++++++++++----- Userland/Libraries/LibDebug/DebugSession.h | 8 ++++--- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp index 9830042a60..b1a97bae4c 100644 --- a/Userland/DevTools/HackStudio/Debugger/Debugger.cpp +++ b/Userland/DevTools/HackStudio/Debugger/Debugger.cpp @@ -21,9 +21,10 @@ void Debugger::initialize( DeprecatedString source_root, Function on_stop_callback, Function on_continue_callback, - Function on_exit_callback) + Function on_exit_callback, + Function on_initialization_progress) { - s_the = new Debugger(source_root, move(on_stop_callback), move(on_continue_callback), move(on_exit_callback)); + s_the = new Debugger(source_root, move(on_stop_callback), move(on_continue_callback), move(on_exit_callback), move(on_initialization_progress)); } bool Debugger::is_initialized() @@ -35,11 +36,13 @@ Debugger::Debugger( DeprecatedString source_root, Function on_stop_callback, Function on_continue_callback, - Function on_exit_callback) + Function on_exit_callback, + Function on_initialization_progress) : m_source_root(source_root) , m_on_stopped_callback(move(on_stop_callback)) , m_on_continue_callback(move(on_continue_callback)) , m_on_exit_callback(move(on_exit_callback)) + , m_on_initialization_progress(move(on_initialization_progress)) { pthread_mutex_init(&m_ui_action_mutex, nullptr); pthread_cond_init(&m_ui_action_cond, nullptr); @@ -137,13 +140,13 @@ Debugger::CreateDebugSessionResult Debugger::create_debug_session() return m_child_setup_callback(); return ErrorOr {}; }; - auto debug_session = Debug::DebugSession::exec_and_attach(m_executable_path, m_source_root, move(child_setup_callback)); + auto debug_session = Debug::DebugSession::exec_and_attach(m_executable_path, m_source_root, move(child_setup_callback), move(m_on_initialization_progress)); VERIFY(!!debug_session); return { debug_session.release_nonnull(), Debug::DebugSession::Running }; } if (m_pid_to_attach.has_value()) { - auto debug_session = Debug::DebugSession::attach(m_pid_to_attach.value(), m_source_root); + auto debug_session = Debug::DebugSession::attach(m_pid_to_attach.value(), m_source_root, move(m_on_initialization_progress)); VERIFY(!!debug_session); return { debug_session.release_nonnull(), Debug::DebugSession::Stopped }; } diff --git a/Userland/DevTools/HackStudio/Debugger/Debugger.h b/Userland/DevTools/HackStudio/Debugger/Debugger.h index edbd8a61ce..eafd7382ba 100644 --- a/Userland/DevTools/HackStudio/Debugger/Debugger.h +++ b/Userland/DevTools/HackStudio/Debugger/Debugger.h @@ -29,7 +29,8 @@ public: DeprecatedString source_root, Function on_stop_callback, Function on_continue_callback, - Function on_exit_callback); + Function on_exit_callback, + Function on_initialization_progress); static bool is_initialized(); @@ -94,7 +95,8 @@ private: DeprecatedString source_root, Function on_stop_callback, Function on_continue_callback, - Function on_exit_callback); + Function on_exit_callback, + Function on_initialization_progress); Debug::DebugInfo::SourcePosition create_source_position(DeprecatedString const& file, size_t line); @@ -130,6 +132,7 @@ private: Function m_on_continue_callback; Function m_on_exit_callback; Function()> m_child_setup_callback; + Function m_on_initialization_progress; }; } diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 55497033ed..82470ece8f 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -1090,6 +1090,10 @@ void HackStudioWidget::initialize_debugger() GUI::MessageBox::show(window(), "Program Exited"sv, "Debugger"sv, GUI::MessageBox::Type::Information); }); GUI::Application::the()->event_loop().wake(); + }, + [this](float progress) { + if (GUI::Application::the()->active_window()) + GUI::Application::the()->active_window()->set_progress(progress * 100); }); } diff --git a/Userland/Libraries/LibDebug/DebugSession.cpp b/Userland/Libraries/LibDebug/DebugSession.cpp index b135814118..7ad41b67db 100644 --- a/Userland/Libraries/LibDebug/DebugSession.cpp +++ b/Userland/Libraries/LibDebug/DebugSession.cpp @@ -17,10 +17,10 @@ namespace Debug { -DebugSession::DebugSession(pid_t pid, DeprecatedString source_root) +DebugSession::DebugSession(pid_t pid, DeprecatedString source_root, Function on_initialization_progress) : m_debuggee_pid(pid) , m_source_root(source_root) - + , m_on_initialization_progress(move(on_initialization_progress)) { } @@ -55,7 +55,8 @@ void DebugSession::for_each_loaded_library(Function DebugSession::exec_and_attach(DeprecatedString const& command, DeprecatedString source_root, - Function()> setup_child) + Function()> setup_child, + Function on_initialization_progress) { auto pid = fork(); @@ -114,7 +115,7 @@ OwnPtr DebugSession::exec_and_attach(DeprecatedString const& comma return {}; } - auto debug_session = adopt_own(*new DebugSession(pid, source_root)); + auto debug_session = adopt_own(*new DebugSession(pid, source_root, move(on_initialization_progress))); // Continue until breakpoint before entry point of main program int wstatus = debug_session->continue_debuggee_and_wait(); @@ -129,7 +130,7 @@ OwnPtr DebugSession::exec_and_attach(DeprecatedString const& comma return debug_session; } -OwnPtr DebugSession::attach(pid_t pid, DeprecatedString source_root) +OwnPtr DebugSession::attach(pid_t pid, DeprecatedString source_root, Function on_initialization_progress) { if (ptrace(PT_ATTACH, pid, 0, 0) < 0) { perror("PT_ATTACH"); @@ -142,7 +143,7 @@ OwnPtr DebugSession::attach(pid_t pid, DeprecatedString source_roo return {}; } - auto debug_session = adopt_own(*new DebugSession(pid, source_root)); + auto debug_session = adopt_own(*new DebugSession(pid, source_root, move(on_initialization_progress))); // At this point, libraries should have been loaded debug_session->update_loaded_libs(); @@ -467,7 +468,17 @@ void DebugSession::update_loaded_libs() return DeprecatedString::formatted("/usr/lib/{}", lib_name); }; + ScopeGuard progress_guard([this]() { + m_on_initialization_progress(0); + }); + + size_t vm_entry_index = 0; + vm_entries.for_each([&](auto& entry) { + ++vm_entry_index; + if (m_on_initialization_progress) + m_on_initialization_progress(vm_entry_index / static_cast(vm_entries.size())); + // TODO: check that region is executable auto vm_name = entry.as_object().get_deprecated_string("name"sv).value(); diff --git a/Userland/Libraries/LibDebug/DebugSession.h b/Userland/Libraries/LibDebug/DebugSession.h index df279698f8..8997cea5dc 100644 --- a/Userland/Libraries/LibDebug/DebugSession.h +++ b/Userland/Libraries/LibDebug/DebugSession.h @@ -27,8 +27,8 @@ namespace Debug { class DebugSession : public ProcessInspector { public: - static OwnPtr exec_and_attach(DeprecatedString const& command, DeprecatedString source_root = {}, Function()> setup_child = {}); - static OwnPtr attach(pid_t pid, DeprecatedString source_root = {}); + static OwnPtr exec_and_attach(DeprecatedString const& command, DeprecatedString source_root = {}, Function()> setup_child = {}, Function on_initialization_progress = {}); + static OwnPtr attach(pid_t pid, DeprecatedString source_root = {}, Function on_initialization_progress = {}); virtual ~DebugSession() override; @@ -131,7 +131,7 @@ public: }; private: - explicit DebugSession(pid_t, DeprecatedString source_root); + explicit DebugSession(pid_t, DeprecatedString source_root, Function on_initialization_progress = {}); // x86 breakpoint instruction "int3" static constexpr u8 BREAKPOINT_INSTRUCTION = 0xcc; @@ -147,6 +147,8 @@ private: // Maps from library name to LoadedLibrary object HashMap> m_loaded_libraries; + + Function m_on_initialization_progress; }; template