summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DevTools/HackStudio/Debugger/BacktraceModel.cpp4
-rw-r--r--DevTools/HackStudio/Debugger/DebugInfoWidget.cpp7
-rw-r--r--DevTools/HackStudio/main.cpp82
-rw-r--r--Libraries/LibDebug/DebugInfo.cpp8
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 {};