# HG changeset patch # User Markus Mützel # Date 1713466759 -7200 # Node ID af2b017a5a7abb5ce140b48c8b648b46c1cd6624 # Parent df60dee3a90157173d9866628a1c9f7077a2d45c Fix segmentation fault when trying to set breakpoint in non-existent method (bug #65610). * libinterp/parse-tree/pt-eval.cc (tree_evaluator::get_user_code): Check if classdef method with given name exists before trying to dereference representation. * test/classdef-debug/test_classdef_breakpints.tst: Add tests for setting breakpoints using method names. * etc/NEWS.9.md: Add note. diff -r df60dee3a901 -r af2b017a5a7a etc/NEWS.9.md --- a/etc/NEWS.9.md Thu Apr 18 18:29:17 2024 +0200 +++ b/etc/NEWS.9.md Thu Apr 18 20:59:19 2024 +0200 @@ -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 df60dee3a901 -r af2b017a5a7a libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Thu Apr 18 18:29:17 2024 +0200 +++ b/libinterp/parse-tree/pt-eval.cc Thu Apr 18 20:59:19 2024 +0200 @@ -2989,7 +2989,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 df60dee3a901 -r af2b017a5a7a test/classdef-debug/test_classdef_breakpoints.tst --- a/test/classdef-debug/test_classdef_breakpoints.tst Thu Apr 18 18:29:17 2024 +0200 +++ b/test/classdef-debug/test_classdef_breakpoints.tst Thu Apr 18 20:59:19 2024 +0200 @@ -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,51 @@ %! 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 +%! ## This should error. But it does not. +%! 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 +88,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);