1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Allow to ignore debugger error breaks

This commit is contained in:
kobewi
2024-04-20 19:52:54 +02:00
parent 74907876d3
commit 7d82704f12
11 changed files with 84 additions and 14 deletions

View File

@@ -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;
@@ -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];

View File

@@ -106,7 +106,7 @@ public:
_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);

View File

@@ -413,17 +413,24 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
ScriptLanguage *script_lang = script_debugger->get_break_language();
ERR_FAIL_NULL(script_lang);
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);
ERR_FAIL_NULL(script_lang);
msg.push_back(script_lang->debug_get_stack_level_count() > 0);
msg.push_back(Thread::get_caller_id());
if (allow_focus_steal_fn) {
allow_focus_steal_fn();
}
send_message("debug_enter", msg);
} else {
ERR_PRINT(error_str);
return;
}
Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE;
@@ -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];
@@ -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 {

View File

@@ -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;

View File

@@ -39,6 +39,7 @@ class ScriptDebugger {
typedef ScriptLanguage::StackInfo StackInfo;
bool skip_breakpoints = false;
bool ignore_error_breaks = false;
HashMap<int, HashSet<StringName>> breakpoints;
@@ -63,6 +64,8 @@ public:
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 {

View File

@@ -615,6 +615,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) {

View File

@@ -188,6 +188,7 @@ public:
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();

View File

@@ -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_button_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));
} else {
ignore_error_breaks->set_button_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons")));
}
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());
@@ -916,6 +929,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_button_icon(get_editor_theme_icon(ignore_error_breaks_value ? SNAME("NotificationDisabled") : SNAME("Notification")));
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")));
@@ -1592,10 +1610,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();
@@ -1895,6 +1917,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);

View File

@@ -113,6 +113,7 @@ private:
int warning_count;
bool skip_breakpoints_value = false;
bool ignore_error_breaks_value = false;
Ref<Script> stack_script;
TabContainer *tabs = nullptr;
@@ -120,6 +121,7 @@ private:
Label *reason = nullptr;
Button *skip_breakpoints = nullptr;
Button *ignore_error_breaks = nullptr;
Button *copy = nullptr;
Button *step = nullptr;
Button *next = nullptr;
@@ -261,6 +263,7 @@ public:
void stop();
void debug_skip_breakpoints();
void debug_ignore_error_breaks();
void debug_copy();
void debug_next();
@@ -308,7 +311,8 @@ public:
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;

View File

@@ -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);
}

View File

@@ -593,6 +593,7 @@ void Main::print_help(const char *p_binary) {
print_help_title("Debug options");
print_help_option("-d, --debug", "Debug (local stdout debugger).\n");
print_help_option("-b, --breakpoints", "Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
print_help_option("--ignore-error-breaks", "If debugger is connected, prevents sending error breakpoints.\n");
print_help_option("--profiling", "Enable profiling in the script debugger.\n");
print_help_option("--gpu-profile", "Show a GPU profile of the tasks that took the most time during frame rendering.\n");
print_help_option("--gpu-validation", "Enable graphics API validation layers for debugging.\n");
@@ -984,6 +985,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool test_rd_support = false;
#endif
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.
@@ -1734,6 +1736,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 XR_DISABLED
} else if (arg == "--xr-mode") {
if (N) {
@@ -1984,7 +1988,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);
}