Skip to content

Commit

Permalink
Allow to ignore debugger error breaks
Browse files Browse the repository at this point in the history
  • Loading branch information
KoBeWi committed Feb 4, 2025
1 parent 0b6a717 commit 020906a
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 14 deletions.
3 changes: 2 additions & 1 deletion core/debugger/engine_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks,
singleton->poll_events(true);
}

void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
if (p_uri.is_empty()) {
return;
Expand Down Expand Up @@ -160,6 +160,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co
// There is a debugger, parse breakpoints.
ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints);
singleton_script_debugger->set_ignore_error_breaks(p_ignore_error_breaks);

for (int i = 0; i < p_breakpoints.size(); i++) {
const String &bp = p_breakpoints[i];
Expand Down
2 changes: 1 addition & 1 deletion core/debugger/engine_debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class EngineDebugger {

_FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; }

static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
static void initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
static void deinitialize();
static void register_profiler(const StringName &p_name, const Profiler &p_profiler);
static void unregister_profiler(const StringName &p_name);
Expand Down
31 changes: 22 additions & 9 deletions core/debugger/remote_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,17 +413,24 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}

ScriptLanguage *script_lang = script_debugger->get_break_language();
const String error_str = script_lang ? script_lang->debug_get_error() : "";
Array msg;
msg.push_back(p_can_continue);
msg.push_back(error_str);
ERR_FAIL_NULL(script_lang);
msg.push_back(script_lang->debug_get_stack_level_count() > 0);
msg.push_back(Thread::get_caller_id() == Thread::get_main_id() ? String(RTR("Main Thread")) : itos(Thread::get_caller_id()));
if (allow_focus_steal_fn) {
allow_focus_steal_fn();
const bool can_break = !(p_is_error_breakpoint && script_debugger->is_ignoring_error_breaks());
const String error_str = script_lang ? script_lang->debug_get_error() : "";

if (can_break) {
Array msg;
msg.push_back(p_can_continue);
msg.push_back(error_str);
msg.push_back(script_lang->debug_get_stack_level_count() > 0);
msg.push_back(Thread::get_caller_id() == Thread::get_main_id() ? String(RTR("Main Thread")) : itos(Thread::get_caller_id()));
if (allow_focus_steal_fn) {
allow_focus_steal_fn();
}
send_message("debug_enter", msg);
} else {
ERR_PRINT(error_str);
return;
}
send_message("debug_enter", msg);

Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE;

Expand Down Expand Up @@ -530,6 +537,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else if (command == "set_skip_breakpoints") {
ERR_FAIL_COND(data.is_empty());
script_debugger->set_skip_breakpoints(data[0]);
} else if (command == "set_ignore_error_breaks") {
ERR_FAIL_COND(data.size() < 1);
script_debugger->set_ignore_error_breaks(data[0]);
} else if (command == "evaluate") {
String expression_str = data[0];
int frame = data[1];
Expand Down Expand Up @@ -669,6 +679,9 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo
} else if (p_cmd == "set_skip_breakpoints") {
ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA);
script_debugger->set_skip_breakpoints(p_data[0]);
} else if (p_cmd == "set_ignore_error_breaks") {
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
script_debugger->set_ignore_error_breaks(p_data[0]);
} else if (p_cmd == "break") {
script_debugger->debug(script_debugger->get_break_language());
} else {
Expand Down
8 changes: 8 additions & 0 deletions core/debugger/script_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ bool ScriptDebugger::is_skipping_breakpoints() {
return skip_breakpoints;
}

void ScriptDebugger::set_ignore_error_breaks(bool p_ignore) {
ignore_error_breaks = p_ignore;
}

bool ScriptDebugger::is_ignoring_error_breaks() {
return ignore_error_breaks;
}

void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_is_error_breakpoint) {
ScriptLanguage *prev = break_lang;
break_lang = p_lang;
Expand Down
3 changes: 3 additions & 0 deletions core/debugger/script_debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ScriptDebugger {
typedef ScriptLanguage::StackInfo StackInfo;

bool skip_breakpoints = false;
bool ignore_error_breaks = false;

HashMap<int, HashSet<StringName>> breakpoints;

Expand All @@ -64,6 +65,8 @@ class ScriptDebugger {
ScriptLanguage *get_break_language() { return break_lang; }
void set_skip_breakpoints(bool p_skip_breakpoints);
bool is_skipping_breakpoints();
void set_ignore_error_breaks(bool p_ignore);
bool is_ignoring_error_breaks();
void insert_breakpoint(int p_line, const StringName &p_source);
void remove_breakpoint(int p_line, const StringName &p_source);
_ALWAYS_INLINE_ bool is_breakpoint(int p_line, const StringName &p_source) const {
Expand Down
4 changes: 4 additions & 0 deletions editor/debugger/editor_debugger_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,10 @@ bool EditorDebuggerNode::is_skip_breakpoints() const {
return get_current_debugger()->is_skip_breakpoints();
}

bool EditorDebuggerNode::is_ignore_error_breaks() const {
return get_default_debugger()->is_ignore_error_breaks();
}

void EditorDebuggerNode::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
breakpoints[Breakpoint(p_path, p_line)] = p_enabled;
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
Expand Down
1 change: 1 addition & 0 deletions editor/debugger/editor_debugger_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class EditorDebuggerNode : public MarginContainer {
bool get_debug_with_external_editor() { return debug_with_external_editor; }

bool is_skip_breakpoints() const;
bool is_ignore_error_breaks() const;
void set_breakpoint(const String &p_path, int p_line, bool p_enabled);
void set_breakpoints(const String &p_path, const Array &p_lines);
void reload_all_scripts();
Expand Down
30 changes: 29 additions & 1 deletion editor/debugger/script_editor_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ void ScriptEditorDebugger::debug_skip_breakpoints() {
_put_msg("set_skip_breakpoints", msg, debugging_thread_id != Thread::UNASSIGNED_ID ? debugging_thread_id : Thread::MAIN_ID);
}

void ScriptEditorDebugger::debug_ignore_error_breaks() {
ignore_error_breaks_value = !ignore_error_breaks_value;
if (ignore_error_breaks_value) {
ignore_error_breaks->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor, tests=yes)

no member named 'set_icon' in 'Button'

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no member named 'set_icon' in 'Button'

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor (target=editor, tests=yes)

'set_icon': is not a member of 'Button'

Check failure on line 108 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)

no member named 'set_icon' in 'Button'
} else {
ignore_error_breaks->set_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons")));

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor, tests=yes)

no member named 'set_icon' in 'Button'

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no member named 'set_icon' in 'Button'

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor (target=editor, tests=yes)

'set_icon': is not a member of 'Button'

Check failure on line 110 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)

no member named 'set_icon' in 'Button'
}

Array msg;
msg.push_back(ignore_error_breaks_value);
_put_msg("set_ignore_error_breaks", msg);
}

void ScriptEditorDebugger::debug_next() {
ERR_FAIL_COND(!is_breaked());

Expand Down Expand Up @@ -879,6 +892,11 @@ void ScriptEditorDebugger::_notification(int p_what) {
tabs->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));

skip_breakpoints->set_button_icon(get_editor_theme_icon(skip_breakpoints_value ? SNAME("DebugSkipBreakpointsOn") : SNAME("DebugSkipBreakpointsOff")));
ignore_error_breaks->set_icon(get_editor_theme_icon(ignore_error_breaks_value ? SNAME("NotificationDisabled") : SNAME("Notification")));

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🍎 macOS / Editor (target=editor, tests=yes)

no member named 'set_icon' in 'Button'

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🤖 Android / Editor (target=editor)

no member named 'set_icon' in 'Button'

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

no member named 'set_icon' in 'Button'

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor (target=editor, tests=yes)

'set_icon': is not a member of 'Button'

Check failure on line 895 in editor/debugger/script_editor_debugger.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)

no member named 'set_icon' in 'Button'
ignore_error_breaks->add_theme_color_override("icon_normal_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
ignore_error_breaks->add_theme_color_override("icon_hover_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
ignore_error_breaks->add_theme_color_override("icon_pressed_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
ignore_error_breaks->add_theme_color_override("icon_focus_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
copy->set_button_icon(get_editor_theme_icon(SNAME("ActionCopy")));
step->set_button_icon(get_editor_theme_icon(SNAME("DebugStep")));
next->set_button_icon(get_editor_theme_icon(SNAME("DebugNext")));
Expand Down Expand Up @@ -1555,10 +1573,14 @@ void ScriptEditorDebugger::reload_scripts(const Vector<String> &p_script_paths)
_put_msg("reload_scripts", Variant(p_script_paths).operator Array(), debugging_thread_id != Thread::UNASSIGNED_ID ? debugging_thread_id : Thread::MAIN_ID);
}

bool ScriptEditorDebugger::is_skip_breakpoints() {
bool ScriptEditorDebugger::is_skip_breakpoints() const {
return skip_breakpoints_value;
}

bool ScriptEditorDebugger::is_ignore_error_breaks() const {
return ignore_error_breaks_value;
}

void ScriptEditorDebugger::_error_activated() {
TreeItem *selected = error_tree->get_selected();

Expand Down Expand Up @@ -1859,6 +1881,12 @@ ScriptEditorDebugger::ScriptEditorDebugger() {
skip_breakpoints->set_tooltip_text(TTR("Skip Breakpoints"));
skip_breakpoints->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_skip_breakpoints));

ignore_error_breaks = memnew(Button);
ignore_error_breaks->set_flat(true);
ignore_error_breaks->set_tooltip_text(TTR("Ignore Error Breaks"));
hbc->add_child(ignore_error_breaks);
ignore_error_breaks->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_ignore_error_breaks));

hbc->add_child(memnew(VSeparator));

copy = memnew(Button);
Expand Down
6 changes: 5 additions & 1 deletion editor/debugger/script_editor_debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,15 @@ class ScriptEditorDebugger : public MarginContainer {
int warning_count;

bool skip_breakpoints_value = false;
bool ignore_error_breaks_value = false;
Ref<Script> stack_script;

TabContainer *tabs = nullptr;

Label *reason = nullptr;

Button *skip_breakpoints = nullptr;
Button *ignore_error_breaks = nullptr;
Button *copy = nullptr;
Button *step = nullptr;
Button *next = nullptr;
Expand Down Expand Up @@ -262,6 +264,7 @@ class ScriptEditorDebugger : public MarginContainer {
void stop();

void debug_skip_breakpoints();
void debug_ignore_error_breaks();
void debug_copy();

void debug_next();
Expand Down Expand Up @@ -309,7 +312,8 @@ class ScriptEditorDebugger : public MarginContainer {
void reload_all_scripts();
void reload_scripts(const Vector<String> &p_script_paths);

bool is_skip_breakpoints();
bool is_skip_breakpoints() const;
bool is_ignore_error_breaks() const;

virtual Size2 get_minimum_size() const override;

Expand Down
4 changes: 4 additions & 0 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie, const V
args.push_back("--skip-breakpoints");
}

if (EditorDebuggerNode::get_singleton()->is_ignore_error_breaks()) {
args.push_back("--ignore-error-breaks");
}

if (!p_scene.is_empty()) {
args.push_back(p_scene);
}
Expand Down
5 changes: 4 additions & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool upwards = false;
String debug_uri = "";
bool skip_breakpoints = false;
bool ignore_error_breaks = false;
String main_pack;
bool quiet_stdout = false;
int separate_thread_render = -1; // Tri-state: -1 = not set, 0 = false, 1 = true.
Expand Down Expand Up @@ -1719,6 +1720,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->disable_crash_handler();
} else if (arg == "--skip-breakpoints") {
skip_breakpoints = true;
} else if (I->get() == "--ignore-error-breaks") {
ignore_error_breaks = true;
#ifndef _3D_DISABLED
} else if (arg == "--xr-mode") {
if (N) {
Expand Down Expand Up @@ -1945,7 +1948,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF(PropertyInfo(Variant::INT, "network/limits/debugger/max_errors_per_second", PROPERTY_HINT_RANGE, "1,200,1,or_greater"), 400);
GLOBAL_DEF(PropertyInfo(Variant::INT, "network/limits/debugger/max_warnings_per_second", PROPERTY_HINT_RANGE, "1,200,1,or_greater"), 400);

EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints, []() {
EngineDebugger::initialize(debug_uri, skip_breakpoints, ignore_error_breaks, breakpoints, []() {
if (editor_pid) {
DisplayServer::get_singleton()->enable_for_stealing_focus(editor_pid);
}
Expand Down

0 comments on commit 020906a

Please sign in to comment.