summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2020-08-15 10:58:16 +0300
committerAndreas Kling <kling@serenityos.org>2020-08-15 15:06:35 +0200
commit7eac9fe10e6917aaa24b6ca8f332f275aab74206 (patch)
treeb08665567542415b931b4e4ae3bb37e38691f3c6
parent310063fed8a005b74dd2472ce812158fbb34d879 (diff)
downloadserenity-7eac9fe10e6917aaa24b6ca8f332f275aab74206.zip
HackStudio: Support debugging library code
We can now step into library code in the debugger. Since we now need the whole source code of our libraries (and not just the headers), we clone the whole serenity git repo into /usr/share/serenity.
-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 {};