# HG changeset patch # User Arun Giridhar # Date 1713545840 14400 # Node ID 066a27297ba37172ea9466903b0fc75bb0c7c2fa # Parent e4e172cb662c18200691f7b174a124c5f2dbe662# Parent 69eb4c27d8c80e8a21a96fc69cf76c0f27c30486 maint: Merge default to bytecode-interpreter diff -r e4e172cb662c -r 066a27297ba3 etc/NEWS.9.md --- a/etc/NEWS.9.md Thu Apr 18 13:15:27 2024 -0400 +++ b/etc/NEWS.9.md Fri Apr 19 12:57:20 2024 -0400 @@ -17,6 +17,8 @@ - Correctly scale figure position on screen with DPI scaling (high DPI). - `profile ('on')` now clears any existing profile data as the documentation states (bug #65595). +- Fix segmentation fault when trying to set breakpoint in non-existent method + of `classdef` class (bug #65610). ### GUI diff -r e4e172cb662c -r 066a27297ba3 libinterp/corefcn/debug.cc --- a/libinterp/corefcn/debug.cc Thu Apr 18 13:15:27 2024 -0400 +++ b/libinterp/corefcn/debug.cc Fri Apr 19 12:57:20 2024 -0400 @@ -185,7 +185,7 @@ class_name, lines, condition); if (lines.size () == 0) - lines.insert (1); + lines.insert (-1); if (symbol_name != "") { diff -r e4e172cb662c -r 066a27297ba3 libinterp/parse-tree/bp-table.cc --- a/libinterp/parse-tree/bp-table.cc Thu Apr 18 13:15:27 2024 -0400 +++ b/libinterp/parse-tree/bp-table.cc Fri Apr 19 12:57:20 2024 -0400 @@ -797,6 +797,9 @@ if (is_function ()) return find_fcn_by_line (m_fcn, line); + if (line < 0) + return nullptr; + return m_cls.get_method (line).user_code_value (true); } @@ -834,7 +837,7 @@ { if (m_methods_cache.empty ()) { - // Not the most effecient, but reuses code: + // Not the most efficient, but reuses code: const std::map& map = m_cls.get_method_map (false, true); for (auto iter = map.cbegin (); iter != map.cend (); ++iter) @@ -872,6 +875,10 @@ { octave_user_code *dbg_fcn = user_code (lineno); + if (! dbg_fcn) + error ("add_breakpoints_in_function: unable to find function '%s'\n", + fcn_ident.c_str ()); + // We've found the right (sub)function. Now insert the breakpoint. bp_lines line_info; line_info.insert (lineno); @@ -879,14 +886,13 @@ bp_lines ret_one; std::string ident = fcn_ident; - if (! user_code.is_function () && fcn_ident[0] != '@' && dbg_fcn) + if (! user_code.is_function () && fcn_ident[0] != '@') { // identifier of the form @class_name/method_name ident = "@" + fcn_ident + "/" + dbg_fcn->name (); } - if (dbg_fcn && add_breakpoint_1 (dbg_fcn, ident, line_info, - condition, ret_one)) + if (add_breakpoint_1 (dbg_fcn, ident, line_info, condition, ret_one)) { if (! ret_one.empty ()) { diff -r e4e172cb662c -r 066a27297ba3 libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Thu Apr 18 13:15:27 2024 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Fri Apr 19 12:57:20 2024 -0400 @@ -3063,7 +3063,13 @@ cdef_class cls = cdm.find_class (dispatch_type, false); if (cls.ok () && cls.get_name () == dispatch_type) - fcn = cls.find_method (method).get_function (); + { + cdef_method meth = cls.find_method (method); + if (meth.ok () && meth.get_name () == method) + fcn = meth.get_function (); + else + return nullptr; + } // If there is no classdef method, then try legacy classes. if (fcn.is_undefined ()) diff -r e4e172cb662c -r 066a27297ba3 scripts/profiler/profile.m --- a/scripts/profiler/profile.m Thu Apr 18 13:15:27 2024 -0400 +++ b/scripts/profiler/profile.m Fri Apr 19 12:57:20 2024 -0400 @@ -41,7 +41,7 @@ ## with @code{T = profile ("info")}. ## ## @item profile clear -## Clear all collected profiler data. +## Clear all collected profiler data and stop profiling. ## ## @item profile resume ## Restart profiling without clearing the old data. All newly collected @@ -84,18 +84,16 @@ __profiler_enable__ (false); case "clear" + if (__profiler_enable__ ()) + __profiler_enable__ (false); + endif __profiler_reset__ (); case "resume" __profiler_enable__ (true); case "status" - enabled = __profiler_enable__ (); - if (enabled) - enabled = "on"; - else - enabled = "off"; - endif + enabled = ifelse (__profiler_enable__ (), 'on', 'off'); retval = struct ("ProfilerStatus", enabled); case "info" @@ -156,5 +154,4 @@ ## Test input validation %!error profile () -%!error profile ("on", 2) %!error profile ("INVALID_OPTION") diff -r e4e172cb662c -r 066a27297ba3 test/classdef-debug/test-classdef-breakpoints.tst --- a/test/classdef-debug/test-classdef-breakpoints.tst Thu Apr 18 13:15:27 2024 -0400 +++ b/test/classdef-debug/test-classdef-breakpoints.tst Fri Apr 19 12:57:20 2024 -0400 @@ -1,4 +1,5 @@ -## Test script for setting breakpoints in classdefs using line numbers. +## Test script for setting breakpoints in classdefs +## using line numbers or method names. %!function assert_dbstatus (bp0) %! dbs = dbstatus (); @@ -10,6 +11,7 @@ %! endif %!endfunction +## Set breakpoints by line numbers %!test <*46451> %! if (isguirunning ()) %! orig_show_dbg = __event_manager_gui_preference__ ("editor/show_dbg_file", @@ -33,6 +35,50 @@ %! endif %! end_unwind_protect +## Set breakpoints by method name +%!test +%! if (isguirunning ()) +%! orig_show_dbg = __event_manager_gui_preference__ ("editor/show_dbg_file", +%! "false"); +%! endif +%! unwind_protect +%! ## Add breakpoint in constructor +%! dbstop @classdef_breakpoints/classdef_breakpoints; +%! assert_dbstatus ([7]); +%! +%! ## Add breakpoints in methods. +%! dbstop @classdef_breakpoints/foo; +%! dbstop @classdef_breakpoints/bar; +%! assert_dbstatus ([7, 10, 13]); +%! +%! ## Remove breakpoint from one method. +%! dbclear @classdef_breakpoints/foo; +%! assert_dbstatus ([7, 13]); +%! +%! ## Clear all breakpoints, none should be left. +%! dbclear classdef_breakpoints; +%! assert_dbstatus ([]); +%! unwind_protect_cleanup +%! if (isguirunning ()) +%! __event_manager_gui_preference__ ("editor/show_dbg_file", orig_show_dbg); +%! endif +%! end_unwind_protect + +## Try to add breakpoint in non-existent method +%!test <65610*> +%! if (isguirunning ()) +%! orig_show_dbg = __event_manager_gui_preference__ ("editor/show_dbg_file", +%! "false"); +%! endif +%! unwind_protect +%! fail ("dbstop @classdef_breakpoints/baz;", "unable to find function"); +%! unwind_protect_cleanup +%! dbclear classdef_breakpoints; +%! if (isguirunning ()) +%! __event_manager_gui_preference__ ("editor/show_dbg_file", orig_show_dbg); +%! endif +%! end_unwind_protect + %!test <46451> %! if (isguirunning ()) %! orig_show_dbg = __event_manager_gui_preference__ ("editor/show_dbg_file", @@ -41,7 +87,7 @@ %! unwind_protect %! ## Add breakpoint in local function. %! dbstop classdef_breakpoints 19; -%! assert_dbstatus ([7, 13, 20]); +%! assert_dbstatus ([20]); %! unwind_protect_cleanup %! if (isguirunning ()) %! __event_manager_gui_preference__ ("editor/show_dbg_file", orig_show_dbg);