diff options
-rw-r--r-- | DevTools/HackStudio/Debugger/BacktraceModel.cpp | 4 | ||||
-rw-r--r-- | DevTools/HackStudio/Debugger/DebugInfoWidget.cpp | 7 | ||||
-rw-r--r-- | DevTools/HackStudio/main.cpp | 82 | ||||
-rw-r--r-- | Libraries/LibDebug/DebugInfo.cpp | 8 |
4 files changed, 69 insertions, 32 deletions
diff --git a/DevTools/HackStudio/Debugger/BacktraceModel.cpp b/DevTools/HackStudio/Debugger/BacktraceModel.cpp index 8cbd82627c..947a8a1662 100644 --- a/DevTools/HackStudio/Debugger/BacktraceModel.cpp +++ b/DevTools/HackStudio/Debugger/BacktraceModel.cpp @@ -57,12 +57,12 @@ Vector<BacktraceModel::FrameInfo> BacktraceModel::create_backtrace(const DebugSe String name = debug_session.debug_info().name_of_containing_function(current_instruction); if (name.is_null()) { dbg() << "BacktraceModel: couldn't find containing function for address: " << (void*)current_instruction; - break; + name = "<missing>"; } frames.append({ name, current_instruction, current_ebp }); current_instruction = Debugger::the().session()->peek(reinterpret_cast<u32*>(current_ebp + 4)).value(); current_ebp = Debugger::the().session()->peek(reinterpret_cast<u32*>(current_ebp)).value(); - } while (current_ebp); + } while (current_ebp && current_instruction); return frames; } diff --git a/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp b/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp index 2b310fa7dd..4e0b7a8fd0 100644 --- a/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp +++ b/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp @@ -96,7 +96,12 @@ void DebugInfoWidget::update_state(const DebugSession& debug_session, const Ptra { m_variables_view->set_model(VariablesModel::create(regs)); m_backtrace_view->set_model(BacktraceModel::create(debug_session, regs)); - m_backtrace_view->selection().set(m_backtrace_view->model()->index(0)); + auto selected_index = m_backtrace_view->model()->index(0); + if (!selected_index.is_valid()) { + dbg() << "Warning: DebugInfoWidget: backtrace selected index is invalid"; + return; + } + m_backtrace_view->selection().set(selected_index); } void DebugInfoWidget::program_stopped() diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index aa7d91a3ea..9dc9c79e6a 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -119,7 +119,13 @@ static void set_edit_mode(EditMode mode) } } -static EditorWrapper& current_editor_wrapper() +static void build(TerminalWrapper&); +static void run(TerminalWrapper&); +void open_project(String); +void open_file(const String&); +bool make_is_available(); + +EditorWrapper& current_editor_wrapper() { ASSERT(g_current_editor_wrapper); return *g_current_editor_wrapper; @@ -130,15 +136,30 @@ GUI::TextEditor& current_editor() return current_editor_wrapper().editor(); } -static NonnullRefPtr<EditorWrapper> get_editor_of_file(const String& file) +static String get_full_path_of_serenity_source(const String& file) { - for (auto& wrapper : g_all_editor_wrappers) { - String wrapper_file = wrapper.filename_label().text(); - if (wrapper_file == file || String::format("./%s", wrapper_file.characters()) == file) { - return wrapper; - } + auto path_parts = LexicalPath(file).parts(); + ASSERT(path_parts[0] == ".."); + path_parts.remove(0); + StringBuilder relative_path_builder; + relative_path_builder.join("/", path_parts); + constexpr char SERENITY_LIBS_PREFIX[] = "/usr/src/serenity"; + LexicalPath serenity_sources_base(SERENITY_LIBS_PREFIX); + return String::format("%s/%s", serenity_sources_base.string().characters(), relative_path_builder.to_string().characters()); +} + +NonnullRefPtr<EditorWrapper> get_editor_of_file(const String& file) +{ + String file_path = file; + + // TODO: We can probably do a more specific condition here, something like + // "if (file.starts_with("../Libraries/") || file.starts_with("../AK/"))" + if (file.starts_with("../")) { + file_path = get_full_path_of_serenity_source(file); } - ASSERT_NOT_REACHED(); + + open_file(file_path); + return current_editor_wrapper(); } static String get_project_executable_path() @@ -148,12 +169,6 @@ static String get_project_executable_path() return g_project->path().substring(0, g_project->path().index_of(".").value()); } -static void build(TerminalWrapper&); -static void run(TerminalWrapper&); -void open_project(String); -void open_file(const String&); -bool make_is_available(); - int main(int argc, char** argv) { if (pledge("stdio tty accept rpath cpath wpath shared_buffer proc exec unix fattr thread", nullptr) < 0) { @@ -620,27 +635,38 @@ int main(int argc, char** argv) dbg() << "Could not find source position for address: " << (void*)regs.eip; return Debugger::HasControlPassedToUser::No; } - current_editor_in_execution = get_editor_of_file(source_position.value().file_path); - current_editor_in_execution->editor().set_execution_position(source_position.value().line_number - 1); - debug_info_widget.update_state(debug_session, regs); - continue_action->set_enabled(true); - single_step_action->set_enabled(true); - reveal_action_tab(debug_info_widget); + + Core::EventLoop::main().post_event( + *g_window, + make<Core::DeferredInvocationEvent>( + [&, source_position](auto&) { + current_editor_in_execution = get_editor_of_file(source_position.value().file_path); + current_editor_in_execution->editor().set_execution_position(source_position.value().line_number - 1); + debug_info_widget.update_state(*Debugger::the().session(), regs); + continue_action->set_enabled(true); + single_step_action->set_enabled(true); + reveal_action_tab(debug_info_widget); + })); + Core::EventLoop::wake(); + return Debugger::HasControlPassedToUser::Yes; }, [&]() { dbg() << "Program continued"; - continue_action->set_enabled(false); - single_step_action->set_enabled(false); - if (current_editor_in_execution) { - current_editor_in_execution->editor().clear_execution_position(); - } + Core::EventLoop::main().post_event(*g_window, make<Core::DeferredInvocationEvent>([&](auto&) { + continue_action->set_enabled(false); + single_step_action->set_enabled(false); + if (current_editor_in_execution) { + current_editor_in_execution->editor().clear_execution_position(); + } + })); + Core::EventLoop::wake(); }, [&]() { dbg() << "Program exited"; - debug_info_widget.program_stopped(); - hide_action_tabs(); - Core::EventLoop::main().post_event(*g_window, make<Core::DeferredInvocationEvent>([=](auto&) { + Core::EventLoop::main().post_event(*g_window, make<Core::DeferredInvocationEvent>([&](auto&) { + debug_info_widget.program_stopped(); + hide_action_tabs(); GUI::MessageBox::show(g_window, "Program Exited", "Debugger", GUI::MessageBox::Type::Information); })); Core::EventLoop::wake(); diff --git a/Libraries/LibDebug/DebugInfo.cpp b/Libraries/LibDebug/DebugInfo.cpp index 16ee6131e4..6d66ddae0f 100644 --- a/Libraries/LibDebug/DebugInfo.cpp +++ b/Libraries/LibDebug/DebugInfo.cpp @@ -146,8 +146,14 @@ Optional<DebugInfo::SourcePosition> DebugInfo::get_source_position(u32 target_ad Optional<u32> DebugInfo::get_instruction_from_source(const String& file, size_t line) const { + String file_path = file; + constexpr char SERENITY_LIBS_PREFIX[] = "/usr/src/serenity"; + if (file.starts_with(SERENITY_LIBS_PREFIX)) { + file_path = file.substring(sizeof(SERENITY_LIBS_PREFIX), file.length() - sizeof(SERENITY_LIBS_PREFIX)); + file_path = String::format("../%s", file_path.characters()); + } for (const auto& line_entry : m_sorted_lines) { - if (line_entry.file == file && line_entry.line == line) + if (line_entry.file == file_path && line_entry.line == line) return Optional<u32>(line_entry.address); } return {}; |