mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-08 12:56:23 +03:00
HackStudio: Make Editor ask Debugger if a breakpoint was added/removed
Rather than adding/removing a breakpoint indicator, and then telling the debugger about it and hoping it works, let the debugger tell us if it succeeded and then use that to update the indicator. This prevents the user from adding breakpoints to invalid locations while the debugger is running. It also avoids a couple of scary VERIFY()s. We still allow creating breakpoints in invalid locations while the debugger is *not* running.
This commit is contained in:
parent
3910efb80b
commit
ad59fb7cf0
Notes:
sideshowbarker
2024-07-17 06:38:11 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/ad59fb7cf0 Pull-request: https://github.com/SerenityOS/serenity/pull/22703 Reviewed-by: https://github.com/ADKaster ✅
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
|
||||
* Copyright (c) 2024, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
@ -48,36 +49,44 @@ Debugger::Debugger(
|
||||
pthread_cond_init(&m_ui_action_cond, nullptr);
|
||||
}
|
||||
|
||||
void Debugger::on_breakpoint_change(ByteString const& file, size_t line, BreakpointChange change_type)
|
||||
bool Debugger::change_breakpoint(ByteString const& file, size_t line, BreakpointChange change_type)
|
||||
{
|
||||
auto position = create_source_position(file, line);
|
||||
|
||||
if (change_type == BreakpointChange::Added) {
|
||||
m_breakpoints.append(position);
|
||||
} else {
|
||||
m_breakpoints.remove_all_matching([&](Debug::DebugInfo::SourcePosition const& val) { return val == position; });
|
||||
}
|
||||
|
||||
auto session = Debugger::the().session();
|
||||
if (!session)
|
||||
return;
|
||||
if (session) {
|
||||
auto address = session->get_address_from_source_position(position.file_path, position.line_number);
|
||||
if (!address.has_value()) {
|
||||
dbgln("Warning: couldn't get instruction address from source");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto address = session->get_address_from_source_position(position.file_path, position.line_number);
|
||||
if (!address.has_value()) {
|
||||
dbgln("Warning: couldn't get instruction address from source");
|
||||
// TODO: Currently, the GUI will indicate that a breakpoint was inserted/removed at this line,
|
||||
// regardless of whether we actually succeeded to insert it. (For example a breakpoint on a comment, or an include statement).
|
||||
// We should indicate failure via a return value from this function, and not update the breakpoint GUI if we fail.
|
||||
return;
|
||||
switch (change_type) {
|
||||
case BreakpointChange::Added:
|
||||
if (session->insert_breakpoint(address.value().address)) {
|
||||
m_breakpoints.append(position);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case BreakpointChange::Removed:
|
||||
if (session->remove_breakpoint(address.value().address)) {
|
||||
m_breakpoints.remove_all_matching([&](Debug::DebugInfo::SourcePosition const& val) { return val == position; });
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (change_type == BreakpointChange::Added) {
|
||||
bool success = session->insert_breakpoint(address.value().address);
|
||||
VERIFY(success);
|
||||
} else {
|
||||
bool success = session->remove_breakpoint(address.value().address);
|
||||
VERIFY(success);
|
||||
// No active session, so just modify our internal list of breakpoints
|
||||
switch (change_type) {
|
||||
case BreakpointChange::Added:
|
||||
m_breakpoints.append(position);
|
||||
return true;
|
||||
case BreakpointChange::Removed:
|
||||
m_breakpoints.remove_all_matching([&](Debug::DebugInfo::SourcePosition const& val) { return val == position; });
|
||||
return true;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
bool Debugger::set_execution_position(ByteString const& file, size_t line)
|
||||
@ -125,6 +134,7 @@ void Debugger::start()
|
||||
bool success = m_debug_session->insert_breakpoint(address.value().address);
|
||||
VERIFY(success);
|
||||
} else {
|
||||
// FIXME: Report the invalid breakpoint to the GUI somehow.
|
||||
dbgln("couldn't insert breakpoint");
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
static bool is_initialized();
|
||||
|
||||
void on_breakpoint_change(ByteString const& file, size_t line, BreakpointChange change_type);
|
||||
[[nodiscard]] bool change_breakpoint(ByteString const& file, size_t line, BreakpointChange change_type);
|
||||
bool set_execution_position(ByteString const& file, size_t line);
|
||||
|
||||
void set_executable_path(ByteString const& path) { m_executable_path = path; }
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2018-2022, the SerenityOS developers.
|
||||
* Copyright (c) 2023-2024, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
@ -774,9 +775,10 @@ void Editor::set_semantic_syntax_highlighting(bool value)
|
||||
ErrorOr<void> Editor::add_breakpoint(size_t line_number)
|
||||
{
|
||||
if (!breakpoint_lines().contains_slow(line_number)) {
|
||||
add_gutter_indicator(m_breakpoint_indicator_id, line_number);
|
||||
TRY(breakpoint_lines().try_append(line_number));
|
||||
Debugger::the().on_breakpoint_change(wrapper().filename_title(), line_number, BreakpointChange::Added);
|
||||
if (Debugger::the().change_breakpoint(wrapper().filename_title(), line_number, BreakpointChange::Added)) {
|
||||
add_gutter_indicator(m_breakpoint_indicator_id, line_number);
|
||||
TRY(breakpoint_lines().try_append(line_number));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
@ -784,9 +786,10 @@ ErrorOr<void> Editor::add_breakpoint(size_t line_number)
|
||||
|
||||
void Editor::remove_breakpoint(size_t line_number)
|
||||
{
|
||||
remove_gutter_indicator(m_breakpoint_indicator_id, line_number);
|
||||
breakpoint_lines().remove_first_matching([&](size_t line) { return line == line_number; });
|
||||
Debugger::the().on_breakpoint_change(wrapper().filename_title(), line_number, BreakpointChange::Removed);
|
||||
if (Debugger::the().change_breakpoint(wrapper().filename_title(), line_number, BreakpointChange::Removed)) {
|
||||
remove_gutter_indicator(m_breakpoint_indicator_id, line_number);
|
||||
breakpoint_lines().remove_first_matching([&](size_t line) { return line == line_number; });
|
||||
}
|
||||
}
|
||||
|
||||
ErrorOr<void> Editor::update_git_diff_indicators()
|
||||
|
Loading…
Reference in New Issue
Block a user