bugGNU Octave - Bugs: bug #66930, Octave crashes when classdef has...

 
 

bug #66930: Octave crashes when classdef has multiple declarations of methods

Submitter:  Andreas Bertsatos <pr0m1th3as>
Submitted:  Tue 18 Mar 2025 10:30:29 PM UTC
   
 
Category:  Classdef Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * 10.0.90 Operating System:  * GNU/Linux
Fixed Release:  10.1.0 Planned Release:  10.1.0
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Mon 24 Mar 2025 01:53:14 AM UTC, comment #21: 

Thanks. Earlier today I changed the "test" line to a comment per comment #20.

Looks like this passes CI, so closing as fixed. It can be reopened if there are errors found later.

Arun Giridhar <arungiridhar>
Group Member
Sat 22 Mar 2025 02:12:34 AM UTC, comment #20: 

@Arun: There is not a way to use the %!error construct and tag it with the error number.  I don't think it is that important to do so.  I would just put a comment above the %!error code that references the bug number.

Rik <rik5>
Group administrator
Fri 21 Mar 2025 11:25:51 PM UTC, comment #19: 

I've pushed the changes to stable, with the code change in comment #8 under Dmitri's name.


Marking as ready for test on CI.

TODO:

  • Mark test as fixed after testing on CI, so that breaks get marked as regressions.


  • Tag the following two error lines with the bug number. Is that possible?



## Test class with duplicate definitions for methods (A) and properties (B)
%!test <66930>
%!error <duplicate method>   A = class_bug66930A ([1 2 3], 3);
%!error <duplicate property> B = class_bug66930B ([1 2 3], 3);


Right now the test is tagged with the bug number but not the errors,
and the test does nothing except look for the errors anyway.

Arun Giridhar <arungiridhar>
Group Member
Fri 21 Mar 2025 09:43:30 PM UTC, comment #18: 

I am able to work around the duplication of `horzcat` in scripts/+matlab/+lang/MemoizedFunction.m by changing one of the horzcat to vertcat.

CC Guillaume as the author of memoization -- Can you confirm that one of the horzcat should be vertcat?

Arun Giridhar <arungiridhar>
Group Member
Fri 21 Mar 2025 09:35:52 PM UTC, comment #17: 

I was able to create this BIST (attached).

With the BIST alone but no code change, `make check` ends in a crash:


  classdef/classdef.tst ..........................................free(): double free detected in tcache 2
fatal: caught signal Aborted -- stopping myself...


With the code changes from comment #8, `make check` completes but exposes new unrelated failures:

  classdef/classdef.tst .......................................... pass   39/41   [ 0.077s /  0.077s]
                                                    (reported bug) XFAIL   2


  PASS                            19794
  FAIL                                3
  XFAIL (reported bug)               40
  SKIP (missing feature)             58
  SKIP (run-time condition)          28


The 3 unrelated failures are in the BISTs for memoize.m, because of duplicate definitions there:

>>>>> processing .../scripts/miscellaneous/memoize.m
***** test
 fcn1 = memoize (@sin);
 assert (isa (fcn1, "matlab.lang.MemoizedFunction"));
 fcn1 (pi);
 fcn2 = memoize (@sin);
 fcn2 (2*pi);
 assert (isequal (fcn1, fcn2));
!!!!! test failed
duplicate method 'horzcat' in class 'matlab.lang.MemoizedFunction' in file '.../scripts/+matlab/+lang/MemoizedFunction.m'
***** test
 fcn = memoize (@rand);
 a = fcn ();
 b = fcn ();
 assert (a, b);
 fcn2 = memoize (@rand);
 c = fcn2 ();
 assert (a, c);
!!!!! test failed
duplicate method 'horzcat' in class 'matlab.lang.MemoizedFunction' in file '.../scripts/+matlab/+lang/MemoizedFunction.m'
***** test
 fcn = memoize (@plus);
 fcn.stats;
 stats (fcn);
 clearCache (fcn);
 fcn.clearCache;
!!!!! test failed
duplicate method 'horzcat' in class 'matlab.lang.MemoizedFunction' in file '.../scripts/+matlab/+lang/MemoizedFunction.m'



(file #57048)

Arun Giridhar <arungiridhar>
Group Member
Fri 21 Mar 2025 05:20:19 AM UTC, comment #16: 

So I simplified bug-66930.tst to:

## Check for double method declaration in classdefa
%!test
%! x = dblmethd (1)
%! assert (isequal (lasterr ()(1:16), 'duplicate method')


Now I get:

octave:1> cd ../test/bug-66930/
octave:2> test bug-66930.tst
***** test
 x = dblmethd (1)
 assert (isequal (lasterr ()(1:16), 'duplicate method')
!!!!! test failed
syntax error

>>> function  __test__( )

 x = dblmethd (1)
 assert (isequal (lasterr ()(1:16), 'duplicate method')
endfunction
              ^
octave:3>


So may be we should skip test case for this one.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Fri 21 Mar 2025 04:59:07 AM UTC, comment #15: 

I am having hard time makeing a test case for this bug.
I Have two "bad" classdefs:


$ cat dblmethd.m
classdef dblmethd
  properties
    bar = {}
  endproperties

  methods
    function out = dblmethd (x)
      out.bar = {x};
    endfunction

    function out = cat (dim, varargin)
      out = cat(dim, varargin{:});
    endfunction

    function out = cat (dim, varargin)
      out = cat(dim, varargin{:});
    endfunction
  endmethods
endclassdef


and


$ cat dblprop.m
classdef dblprop
  properties
    bar = {}
    bar = {}
  endproperties

  methods
    function out = dblprop (x)
      out.bar = {x};
    endfunction
  endmethods
endclassdef


So at the command interface with a patched octave:

octave:1> cd ../test/bug-66930/
octave:2> x = dblmethd (1)
error: duplicate method 'cat' in class 'dblmethd' in file '/home/dmitri/src/octave/test/bug-66930/dblmethd.m'
error: called from
    <unknown>
octave:3> err = lasterr ()
err = duplicate method 'cat' in class 'dblmethd' in file '/home/dmitri/src/octave/test/bug-66930/dblmethd.m'
octave:4> assert (strfind(err, 'duplicate'))
octave:5>

Yet with bug-66930.tst:

## Check for double method declaration in classdefa
%!test
%! x = dblmethd (1)
%! [err, ~] = lasterr ()
%! __printf_assert__ ("Err1: %s \n", err)
%! assert (strfind(err, 'duplicate'))

## Check for double property declaration in classdef
%!test
%! x = dblprop (1)
%! [err, ~] = lasterr ()
%! __printf_assert__ ("Err2: %s \n", err)
%! assert (strfind(err, 'duplicate'))

I see:

octave:1> cd ../test/bug-66930/
octave:2> test bug-66930.tst
***** test
 x = dblmethd (1)
 [err, ~] = lasterr ()
 __printf_assert__ ("Err1: %s \n", err)
 assert (strfind(err, 'duplicate'))
!!!!! test failed
duplicate method 'cat' in class 'dblmethd' in file '/home/dmitri/src/octave/test/bug-66930/dblmethd.m'


Dmitri.
--



Dmitri A. Sergatskov <dasergatskov>
Thu 20 Mar 2025 07:40:45 PM UTC, comment #14: 

Detecting the duplicate method and property names seems fairly simple and proposed change in comments seems OK.  The strange stack trace is happening because Octave's error function is really intended to be used for execution errors, not parse errors and this error is happening when the classdef file is still being parsed.  Fixing that issue might require a bit more work.  But I think it is better to have a bad error message than a crash so I'd go ahead with the proposed change now and we can work on improving error reporting in the parser later.

John W. Eaton <jwe>
Group administrator
Thu 20 Mar 2025 01:14:05 AM UTC, comment #13: 

If I just delete the last "vertcat" from your example it will not crash, not even a problem with ASAN.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Wed 19 Mar 2025 11:12:19 PM UTC, comment #12: 

Apparently, during various tests I did on this matter, the core dump occurred only when the 'cat' and 'repmat' methods were duplicated. When using other duplicated methods, some functionality of my classdef did not work as expected, but I didn't get an Octave crash.

I can't recall exactly the code for that behavior I am afraid.
Nevertheless, the octave crash occurs consistently only when 'cat' and 'repmat' methods are duplicated.

Andreas Bertsatos <pr0m1th3as>
Wed 19 Mar 2025 07:06:42 PM UTC, comment #11: 

see also bug #50011

A.R. Burgers <arb>
Wed 19 Mar 2025 05:59:48 PM UTC, comment #10: 

I could eventually figure out how to make a cset, but do not mind if somebody beat me to it :)

WRT test case. I am also not sure how to do that. We would need a .m file, do we make a script to write it out?

Also trying to make a minimal example I oversimplified and now it is not even trigger a crash?! So that would also needs some figuring out.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Wed 19 Mar 2025 09:00:13 AM UTC, comment #9: 

@Dmitri: Your proposed changes look reasonable to me. Thank you for looking into that. (Minor nit: Missing whitespace before the opening parenthesis in "file_name()".)

I don't know why there is no call stack at that point though. Does the error stack look the same when you are trying to instantiate the erroneous class from within a script or a function (instead of directly from the command prompt)?

Maybe, jwe can give a hint why the error is thrown with an empty(?) call stack?

But even with the odd call stack the error message is already quite clear and probably would be sufficient to indicate to a user what is going wrong.

Would you like to prepare a patch (with commit message) for that change?
Ideally, that patch would also add the two test classdefs to the test suite.

Markus Mützel <mmuetzel>
Group administrator
Wed 19 Mar 2025 12:49:06 AM UTC, comment #8: 

With the patch:

diff -r b1417e415254 libinterp/octave-value/cdef-class.cc
--- a/libinterp/octave-value/cdef-class.cc      Tue Mar 18 18:08:53 2025 -0400
+++ b/libinterp/octave-value/cdef-class.cc      Tue Mar 18 20:45:34 2025 -0400
@@ -229,7 +229,19 @@
 void
 cdef_class::cdef_class_rep::install_method (const cdef_method& meth)
 {
-  m_method_map[meth.get_name ()] = meth;
+  std::string method_name = meth.get_name ();
+  auto it = m_method_map.find (method_name);
+  //  Check if a method with the same name already exists before
+  //  installing a new one.
+  if (it != m_method_map.end ())
+    {
+      std::string class_file = file_name();
+      error ("duplicate method '%s' in class '%s' in file '%s'",
+            method_name.c_str (), get_name ().c_str (), class_file.c_str ());
+    }
+
+  // Now safely install the new method
+  m_method_map[method_name] = meth;

   m_member_count++;

@@ -384,7 +396,19 @@
 void
 cdef_class::cdef_class_rep::install_property (const cdef_property& prop)
 {
-  m_property_map[prop.get_name ()] = prop;
+  std::string prop_name = prop.get_name ();
+  auto it = m_property_map.find (prop_name);
+  //  Check if a property with the same name already exists before
+  //  installing a new one.
+  if (it != m_property_map.end ())
+    {
+      std::string class_file = file_name ();
+      error ("duplicate property '%s' in class '%s' in file '%s'",
+            prop_name.c_str (), get_name ().c_str (), class_file.c_str ());
+    }
+
+  m_property_map[prop_name] = prop;
+
   // Register the insertion rank of this property
   m_property_rank_map[prop.get_name ()] = m_member_count;


I see:

octave:2> classfail ([1 2 3], 3)
error: duplicate method 'cat' in class 'classfail' in file '/home/dmitri/scratch/classfail.m'
error: called from
    <unknown>
octave:3> classfail2 ([1 2 3], 3)
error: duplicate property 'bar' in class 'classfail2' in file '/home/dmitri/scratch/classfail2.m'
error: called from
    <unknown>


So, error handling looks wrong. But no crash.

Dmitri.
--


Dmitri A. Sergatskov <dasergatskov>
Wed 19 Mar 2025 12:01:01 AM UTC, comment #7: 

I think we need the same idea for the properties as well.

I attach classfail2.m where the duplicate methods have been removed but duplicate properties are introduced. Calling `classfail2 ([1 2 3], 3)` results in the same crash as before. But commenting out the duplicate properties allows it to work.


(file #57038)

Arun Giridhar <arungiridhar>
Group Member
Tue 18 Mar 2025 11:54:25 PM UTC, comment #6: 

Actually since we already have "method_name":

diff -r b1417e415254 libinterp/octave-value/cdef-class.cc
--- a/libinterp/octave-value/cdef-class.cc      Tue Mar 18 18:08:53 2025 -0400
+++ b/libinterp/octave-value/cdef-class.cc      Tue Mar 18 19:52:41 2025 -0400
@@ -229,7 +229,19 @@
 void
 cdef_class::cdef_class_rep::install_method (const cdef_method& meth)
 {
-  m_method_map[meth.get_name ()] = meth;
+
+  //  Check if a method with the same name already exists before
+  //  installing a new one.
+  std::string method_name = meth.get_name ();
+  auto it = m_method_map.find (method_name);
+  if (it != m_method_map.end ())
+    {
+      error ("duplicate method '%s' in class '%s'", method_name.c_str (), get_name ().c_str ());
+      return;
+    }
+
+  // Now safely install the new method
+  m_method_map[method_name] = meth;

   m_member_count++;


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 18 Mar 2025 11:49:09 PM UTC, comment #5: 

With the diff:

$ hg diff cdef-class.cc
diff -r b1417e415254 libinterp/octave-value/cdef-class.cc
--- a/libinterp/octave-value/cdef-class.cc      Tue Mar 18 18:08:53 2025 -0400
+++ b/libinterp/octave-value/cdef-class.cc      Tue Mar 18 19:47:06 2025 -0400
@@ -229,6 +229,18 @@
 void
 cdef_class::cdef_class_rep::install_method (const cdef_method& meth)
 {
+
+  //  Check if a method with the same name already exists before
+  //  installing a new one.
+  std::string method_name = meth.get_name ();
+  auto it = m_method_map.find (method_name);
+  if (it != m_method_map.end ())
+    {
+      error ("duplicate method '%s' in class '%s'", method_name.c_str (), get_name ().c_str ());
+      return;
+    }
+
+  // Now safely install the new method
   m_method_map[meth.get_name ()] = meth;

   m_member_count++;


I see no crash, but the error message could be improved:

octave:2> classfail ([1 2 3], 3)
error: duplicate method 'cat' in class 'classfail'
error: called from
    <unknown>
octave:3>


Not sure at all if this is the fix or just a workaround.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 18 Mar 2025 11:43:45 PM UTC, comment #4: 

It looks like the best remedy is to prevent the duplicate object from being constructed. Can we get this information from the repcount?

With DEBUG_TRACE switched on everywhere:


octave:3> classfail ([1 2 3], 3)
class: classfail
method block
constructor: classfail
method: repmat
method: cat
method: horzcat
method: vertcat
method: cat
deleting meta.method object (handle)
method: horzcat
deleting meta.method object (handle)
method: vertcat
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
free(): double free detected in tcache 2
fatal: caught signal Aborted -- stopping myself...
Aborted (core dumped)


Arun Giridhar <arungiridhar>
Group Member
Tue 18 Mar 2025 11:38:54 PM UTC, comment #3: 

With DEBUG_TRACE switched on in cdef-object.cc, this is the output:


octave:3> classfail ([1 2 3], 3)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
deleting meta.method object (handle)
free(): double free detected in tcache 2
fatal: caught signal Aborted -- stopping myself...
Aborted (core dumped)


Arun Giridhar <arungiridhar>
Group Member
Tue 18 Mar 2025 11:12:21 PM UTC, comment #2: 

Backtrace with current stable b1417e415254:


octave:3> classfail ([1 2 3], 3)
free(): double free detected in tcache 2

Thread 1 "octave-cli" received signal SIGABRT, Aborted.
0x00007ffff2ea5624 in ?? () from /usr/lib/libc.so.6

(gdb) bt
#0  0x00007ffff2ea5624 in ?? () from /usr/lib/libc.so.6
#1  0x00007ffff2e4bba0 in raise () from /usr/lib/libc.so.6
#2  0x00007ffff2e33582 in abort () from /usr/lib/libc.so.6
#3  0x00007ffff2e343bf in ?? () from /usr/lib/libc.so.6
#4  0x00007ffff2eaf765 in ?? () from /usr/lib/libc.so.6
#5  0x00007ffff2eaf7f3 in ?? () from /usr/lib/libc.so.6
#6  0x00007ffff2eb4aaf in free () from /usr/lib/libc.so.6
#7  0x00007ffff30acb8a in operator delete (ptr=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/del_op.cc:49
#8  0x00007ffff30acb9a in operator delete (ptr=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/del_ops.cc:33
#9  0x00007ffff7fb45a6 in std::__new_allocator<octave_value>::deallocate (this=0x5555557c85f8, __p=<optimized out>,
    __n=<optimized out>) at /usr/include/c++/14.2.1/bits/new_allocator.h:156
#10 std::allocator_traits<std::allocator<octave_value> >::deallocate (__a=..., __p=<optimized out>, __n=<optimized out>)
    at /usr/include/c++/14.2.1/bits/alloc_traits.h:550
#11 std::_Vector_base<octave_value, std::allocator<octave_value> >::_M_deallocate (this=0x5555557c85f8, __p=<optimized out>,
    __n=<optimized out>) at /usr/include/c++/14.2.1/bits/stl_vector.h:389
#12 std::_Vector_base<octave_value, std::allocator<octave_value> >::~_Vector_base (this=this@entry=0x5555557c85f8,
    __in_chrg=<optimized out>) at /usr/include/c++/14.2.1/bits/stl_vector.h:368
#13 0x00007ffff7fb45d5 in std::vector<octave_value, std::allocator<octave_value> >::~vector (this=0x5555557c85f8,
    __in_chrg=<optimized out>) at /usr/include/c++/14.2.1/bits/stl_vector.h:738
#14 0x00007ffff75b5f63 in octave_scalar_map::~octave_scalar_map (this=0x5555557c85f0, __in_chrg=<optimized out>)
    at ../libinterp/corefcn/oct-map.h:176
#15 octave::cdef_object_scalar::~cdef_object_scalar (this=this@entry=0x5555557c85d0, __in_chrg=<optimized out>)
    at ../libinterp/octave-value/cdef-object.h:459
#16 0x00007ffff75b1159 in octave::handle_cdef_object::~handle_cdef_object (this=this@entry=0x5555557c85d0, __in_chrg=<optimized out>)
    at ../libinterp/octave-value/cdef-object.cc:744
#17 0x00007ffff7595c39 in octave::cdef_meta_object_rep::~cdef_meta_object_rep (this=this@entry=0x5555557c85d0,
    __in_chrg=<optimized out>) at /usr/include/c++/14.2.1/bits/new_allocator.h:104
#18 0x00007ffff75b029c in octave::cdef_method::cdef_method_rep::~cdef_method_rep (this=0x5555557c85d0, __in_chrg=<optimized out>)
    at ../libinterp/octave-value/cdef-method.h:58
#19 0x00007ffff75b02a7 in octave::cdef_method::cdef_method_rep::~cdef_method_rep (this=0x5555557c85d0, __in_chrg=<optimized out>)
    at ../libinterp/octave-value/cdef-method.h:58
#20 0x00007ffff75956f0 in octave::cdef_object_rep::destroy (this=<optimized out>) at ../libinterp/octave-value/cdef-object.h:176
#21 0x00007ffff75b0780 in octave::cdef_object_rep::release (this=0x5555557c85d0, obj=...)
    at ../libinterp/octave-value/cdef-object.cc:110
--Type <RET> for more, q to quit, c to continue without paging--c
#22 0x00007ffff7526a58 in octave::cdef_object::operator= (this=0x555555806130, obj=...) at ../libinterp/octave-value/cdef-object.h:217
#23 0x00007ffff7592a53 in octave::cdef_method::operator= (this=<optimized out>, meth=...)
    at ../libinterp/octave-value/cdef-method.h:153
#24 octave::cdef_class::cdef_class_rep::install_method (this=0x5555564ddb40, meth=...) at ../libinterp/octave-value/cdef-class.cc:232
#25 0x00007ffff759b426 in octave::cdef_class::install_method (this=this@entry=0x7fffffffb4b0, meth=...)
    at ../libinterp/octave-value/cdef-class.h:281
#26 0x00007ffff75945b0 in octave::cdef_class::make_meta_class (interp=..., t=t@entry=0x5555557a0c20,
    is_at_folder=is_at_folder@entry=false) at ../libinterp/octave-value/cdef-class.cc:1113
#27 0x00007ffff7727dac in octave::tree_classdef::make_meta_class (this=this@entry=0x5555557a0c20, interp=...,
    is_at_folder=is_at_folder@entry=false) at ../libinterp/parse-tree/pt-classdef.cc:287
#28 0x00007ffff7712ca4 in octave::parse_fcn_file (interp=..., full_file=".../classfail.m", file="classfail",
    dir_name="...", dispatch_type="", package_name="", require_file=true, force_script=false, autoload=false,
    relative_lookup=false) at ../libinterp/parse-tree/oct-parse.yy:5385
#29 0x00007ffff771393f in octave::load_fcn_from_file (file_name=".../classfail.m",
    dir_name="...", dispatch_type="", package_name="", fcn_name="", autoload=false)
    at ../libinterp/parse-tree/oct-parse.yy:5629
#30 0x00007ffff786d037 in octave::fcn_info::fcn_info_rep::find_user_function (this=this@entry=0x5555557b63e0)
    at ../libinterp/corefcn/fcn-info.cc:1058
#31 0x00007ffff786d2df in octave::fcn_info::fcn_info_rep::load_class_constructor (this=this@entry=0x5555557b63e0)
    at ../libinterp/corefcn/fcn-info.cc:131
#32 0x00007ffff786dc22 in octave::fcn_info::fcn_info_rep::xfind (this=this@entry=0x5555557b63e0, search_scope=..., args=...)
    at ../libinterp/corefcn/fcn-info.cc:775
#33 0x00007ffff786defa in octave::fcn_info::fcn_info_rep::find (this=0x5555557b63e0, scope=..., args=...)
    at ../libinterp/corefcn/fcn-info.cc:358
#34 0x00007ffff7b617e1 in octave::fcn_info::find (this=0x7fffffffbb50, search_scope=..., args=...)
    at ../libinterp/corefcn/fcn-info.h:251
#35 octave::symbol_table::fcn_table_find (this=0x5555555c8e10, name="classfail", args=..., search_scope_arg=...)
    at ../libinterp/corefcn/symtab.cc:242
#36 0x00007ffff7b618f2 in octave::symbol_table::find_function (this=this@entry=0x5555555c8e10, name="classfail", args=...,
    search_scope=...) at ../libinterp/corefcn/symtab.cc:289
#37 0x00007ffff774272e in octave::tree_index_expression::evaluate_n (this=0x555555827b50, tw=..., nargout=0)
    at /usr/include/c++/14.2.1/bits/shared_ptr_base.h:1066
#38 0x00007ffff7744c3b in octave::tree_index_expression::evaluate (this=<optimized out>, tw=..., nargout=<optimized out>)
    at ../libinterp/parse-tree/pt-idx.h:105
#39 0x00007ffff7738638 in octave::tree_evaluator::visit_statement (this=0x5555555c7d88, stmt=...)
    at ../libinterp/parse-tree/pt-eval.cc:4074
#40 0x00007ffff7749a62 in octave::tree_statement::accept (this=<optimized out>, tw=...) at ../libinterp/parse-tree/pt-stmt.h:125
#41 0x00007ffff772a115 in octave::tree_evaluator::visit_statement_list (this=0x5555555c7d88, lst=...)
    at ../libinterp/parse-tree/pt-eval.cc:4159
#42 0x00007ffff772a57b in octave::tree_statement_list::accept (this=<optimized out>, tw=...) at ../libinterp/parse-tree/pt-stmt.h:215
#43 octave::tree_evaluator::eval (this=this@entry=0x5555555c7d88,
    stmt_list=std::shared_ptr<octave::tree_statement_list> (use count 2, weak count 0) = {...}, interactive=true)
    at ../libinterp/parse-tree/pt-eval.cc:1000
#44 0x00007ffff7731a93 in octave::tree_evaluator::repl (this=this@entry=0x5555555c7d88) at ../libinterp/corefcn/interpreter.h:167
#45 0x00007ffff7a17a4a in octave::interpreter::main_loop (this=this@entry=0x5555555c7c80) at ../libinterp/corefcn/interpreter.cc:1336
#46 0x00007ffff7a1fe34 in octave::interpreter::execute (this=0x5555555c7c80) at ../libinterp/corefcn/interpreter.cc:897
#47 0x00007ffff72a96b8 in octave::cli_application::execute (this=this@entry=0x7fffffffc1b0) at ../libinterp/octave.cc:443
#48 0x0000555555556543 in main (argc=8, argv=0x7fffffffc508) at ../src/main-cli.cc:150
(gdb)


Arun Giridhar <arungiridhar>
Group Member
Tue 18 Mar 2025 10:58:14 PM UTC, comment #1: 

I tried with an octave compiled with UBSAN:

octave:2> classfail ([1 2 3], 3)
../libinterp/octave-value/ov.h:348:27: runtime error: member access within address 0x7f42c03a0600 which does not point to an object of type 'octave_base_value'
0x7f42c03a0600: note: object has invalid vptr
 00 00 00 00  a0 03 2c f4 07 00 00 00  f7 07 f3 58 2a fe 04 10  08 06 3a c0 42 7f 00 00  70 a1 9c 09
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../libinterp/octave-value/ov.h:348:27
free(): double free detected in tcache 2
fatal: caught signal Aborted -- stopping myself...
Aborted (core dumped)

The core dump is attached.

Dmitri.
--


(file #57037)

Dmitri A. Sergatskov <dasergatskov>
Tue 18 Mar 2025 10:30:29 PM UTC, original submission:  

I just noticed an Octave 9.1 crash while trying to run a class constructor, where there are multiple declarations of the same method. I know that this is a user error, since you only define a method once in a classdef file, on the other hand, Octave should not crash and exit even when the user screws up.
I run the same classdef on 10.0.90 and the crash persists. So perhaps this should be evaluated before 10.1 release.

run

classfail ([1 2 3], 3)

to crash Octave

Andreas Bertsatos <pr0m1th3as>

 

Attached Files

Attached Files
file #57048:  BIST.patch added by arungiridhar (2.3KiB - text/x-patch)
file #57038:  classfail2.m added by arungiridhar (574B - text/x-objcsrc)
file #57037:  classdef_crash.txt.gz added by dasergatskov (4.8KiB - application/gzip)
file #57034:  classfail.m added by pr0m1th3as (790B - text/x-objcsrc)

(Note: upload size limit is set to 16MiB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by arungiridhar
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by arb (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by mmuetzel
  • -email is unavailable- added by arungiridhar (Posted a comment)
  • -email is unavailable- added by dasergatskov (Updated the item)
  • -email is unavailable- added by pr0m1th3as (Submitted the item)
  •  

    Votes

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    History

    Follow 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-03-24 arungiridhar StatusReady For Test Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 10.1.0
    2025-03-21 arungiridhar StatusNone Ready For Test
        Planned ReleaseNone 10.1.0
    2025-03-21 arungiridhar Carbon-Copy- Added gyom
    2025-03-21 arungiridhar Attached File- Added BIST.patch, #57048
    2025-03-19 mmuetzel Carbon-Copy- Added jwe
    2025-03-19 arungiridhar Attached File- Added classfail2.m, #57038
    2025-03-18 dasergatskov Attached File- Added classdef_crash.txt.gz, #57037
    2025-03-18 pr0m1th3as Attached File- Added classfail.m, #57034

    Back to the top

    Powered by Savane 3.16.
    Corresponding source code