bugGNU Octave - Bugs: bug #61821, segfault using tree_parameter_list...

 
 

bug #61821: segfault using tree_parameter_list in oct file

Submitted by:  None
Submitted on:  Fri 14 Jan 2022 09:38:29 AM UTC  
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Confirmed Assigned to:  None
Originator Name:  Originator Email:  -email is unavailable-
Open/Closed:  Open Release:  7.0.90
Operating System:  Microsoft Windows

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

( Jump to the original submission)

Fri 21 Jan 2022 04:37:20 AM UTC, comment #10: 

Inspecting function arguments and return values shows that octave_user_function::define_ret_list() doesn't work correctly. The function signature is:

octave_user_function *
octave_user_function::define_ret_list (octave::tree_parameter_list *t)
{
  m_ret_list = t;

  return this;
}

 I extracted the disassembly of "define_ret_list" both for Octave 6.3.0 and 7.0.90 (It's the first time I am using assembly):

Octave 6.3.0

0x00edabb0 <+0>:     mov    0x4(%esp),%edx
0x00edabb4 <+4>:     mov    %ecx,%eax
0x00edabb6 <+6>:     mov    %edx,0xc0(%ecx)
0x00edabbc <+12>:    ret    $0x4
0x00edabbf <+15>:    nop

Octave 7.0.90

0x00df95a0 <+0>:     mov    0x4(%esp),%edx
0x00df95a4 <+4>:     mov    %ecx,%eax
0x00df95a6 <+6>:     mov    %edx,0xd4(%ecx)
0x00df95ac <+12>:    ret    $0x4
0x00df95af <+15>:    nop

It computes the offset of "m_ret_list" from the beginning of the class and puts "t" in that address. In Octave 6.3.0 the offset is correctly computed as 0xc0 while for Octave 7.0.90 it wrongly computed as 0xd4, therefore define_ret_list(t)  puts "t" in a wrong address. Actually instead of changing the member "m_ret_list" it changes "m_end_location_line".

It appears that GCC 11.2.0 that bundled with Octave 7.0.90 has a bug.

Anonymous
Mon 17 Jan 2022 03:09:55 PM UTC, comment #9: 

> I think that segfault can be explained by symbol visibility.


Rest assured that Octave 7 (including 7.0.90) for Windows is not compiled with visibility flags. All symbols are exported (just like in prior versions of Octave).

Markus Mützel <mmuetzel>
Project Member
Mon 17 Jan 2022 02:56:36 PM UTC, comment #8: 

Regarding the comment #3:

>Is it possible to see your application or package that does not work with the restricted symbol visibility?


Sure! I think you have seen it: https://github.com/shsajjadi/OctaveCoder

Please consider that I don't want to impose my package and I think there are possibly a limited number of packages that depend on such non public features. Therefor if disabling the visibility makes Octave more faster and reliable go forward and close this issue as won't fix.

I think that segfault can be explained by symbol visibility. Both coder and the example encounter segfault permanently.

I have relatively limited insight and some of the contents of my previous comment are from googling. My writing skill is also limited, sorry!
I periodically fill bugs anonymously and provide some suggestions that some of them has been rejected.

Discourse is a good place for such discussions. I can suggest multiple ideas here or on discourse about Octave but discussion should be converted to sensible result (code). I know that there are a few developers here that don't have time even to respond to bug reports. I appreciate your efforts of Octave development. Thank you very much!

Anonymous
Mon 17 Jan 2022 02:18:12 PM UTC, comment #7: 

Tried again with the 32-bit version of Octave. With it, I can reproduce the crash.

Top of the backtrace:

(gdb) c
Continuing.
[Thread 3448.0x3ee8 exited with code 0]
[Thread 3448.0x1a3c exited with code 0]
[New Thread 3448.0x5644]

Thread 18 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 3448.0x54c0]
0x6c08172d in std::__cxx11::list<octave::tree_decl_elt*, std::allocator<octave::tree_decl_elt*> >::empty (this=<optimized out>) at d:/svn/octave/test/octave~2.90-/octave~1.90-/mingw32/lib/gcc/i686-w64-mingw32/11.2.0/include/c++/bits/stl_list.h:1056
1056          { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }
(gdb) bt
#0  0x6c08172d in std::__cxx11::list<octave::tree_decl_elt*, std::allocator<octave::tree_decl_elt*> >::empty (
    this=<optimized out>)
    at d:/svn/octave/test/octave~2.90-/octave~1.90-/mingw32/lib/gcc/i686-w64-mingw32/11.2.0/include/c++/bits/stl_list.h:1056
#1  octave::base_list<octave::tree_decl_elt*>::empty (this=<optimized out>)
    at d:/svn/octave/test/octave~2.90-/octave~1.90-/mingw32/include/octave-7.0.90/octave/base-list.h:50
#2  Fparams (args=..., nargout=0) at params.cc:15
#3  0x6ea1009c in liboctinterp-9!_ZN14octave_builtin7executeERN6octave14tree_evaluatorEiRK17octave_value_list ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#4  0x6ea4722e in liboctinterp-9!_ZN15octave_function4callERN6octave14tree_evaluatorEiRK17octave_value_list ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#5  0x6eb19e40 in liboctinterp-9!_ZN6octave15tree_identifier10evaluate_nERNS_14tree_evaluatorEi ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#6  0x6f092e75 in liboctinterp-9!_ZN6octave15tree_identifier8evaluateERNS_14tree_evaluatorEi ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#7  0x6eb15c9f in liboctinterp-9!_ZN6octave14tree_evaluator15visit_statementERNS_14tree_statementE ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#8  0x6eb04d89 in liboctinterp-9!_ZN6octave14tree_evaluator20visit_statement_listERNS_19tree_statement_listE ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#9  0x6eb062ed in liboctinterp-9!_ZN6octave14tree_evaluator4evalERSt10shared_ptrINS_19tree_statement_listEEb ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#10 0x6eb11f76 in liboctinterp-9!_ZN6octave14tree_evaluator4replEv ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#11 0x6edd04eb in liboctinterp-9!_ZN6octave11interpreter7executeEv ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctinterp-9.dll
#12 0x6c30b7e0 in liboctgui-6!_ZN6octave19interpreter_qobject7executeEv ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\liboctgui-6.dll
#13 0x66b20bbd in ZN14QMetaCallEvent13placeMetaCallEP7QObject ()
   from D:\SVN\Octave\test\OCTAVE~2.90-\OCTAVE~1.90-\mingw32\bin\Qt5Core.dll

Markus Mützel <mmuetzel>
Project Member
Mon 17 Jan 2022 02:08:47 PM UTC, comment #6: 

No crash here:

GNU Octave, version 7.0.90
Copyright (C) 2021-2022 The Octave Project Developers.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "x86_64-w64-mingw32".

Additional information about Octave is available at https://www.octave.org.

Please contribute if you find this software useful.
For more information, visit https://www.octave.org/get-involved.html

Read https://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

>> mkoctfile params.cc
>> params
ans = 1
>> a=params
a = 1

Markus Mützel <mmuetzel>
Project Member
Mon 17 Jan 2022 01:57:12 PM UTC, comment #5: 

@mmuetzel: Can you reproduce the problem of comment #0?

Kai Torben Ohlhus <siko1056>
Project Member
Mon 17 Jan 2022 12:39:51 PM UTC, comment #4: 

Compiling with visibility flags isn't completely implemented for Octave 7. It is disabled by default (and only thought to be used by developers at this point).
Any help in completing that task is very much appreciated. Preferably in the form of patches submitted to savannah. (Please open new reports for those if you like.)

Since the version of Octave for Windows is not compiled with visibility flags (i.e., it's exporting all symbols indiscriminately), that's probably not the cause for the issue in comment #0.

Markus Mützel <mmuetzel>
Project Member
Mon 17 Jan 2022 12:16:56 PM UTC, comment #3: 

The issue seems to be larger than the toy example.  Luckily for this reason Octave's release candidates are for: finding problems before the official release 🙂  Thus thanks for trying out in time.

Is it possible to see your application or package that does not work with the restricted symbol visibility?

You seem to have lots of insight into MS Windows DLL development.
 Would you like to join in the dicussion on Octave Discourse?

Just for the sake of completenes: does the toy example of the original post cause reliably a segmentation fault on MS Windows, as I cannot reproduce it?

Kai Torben Ohlhus <siko1056>
Project Member
Mon 17 Jan 2022 11:44:52 AM UTC, comment #2: 

Thank you for your attention!
I'm on Windows 7 32-bit. I downloaded octave-7.0.90-w32.7z from alpha.gnu.org.
Initially my guess was the issue may be a config bug or it possibly may be related to gcc bug but after I found that it may be related to visibility of symbols. I searched the bug archive for the "visibility" word and received to these threads:
  oct-file has an undefined symbol https://savannah.gnu.org/bugs/?60567
  build fails on macOS with visibility settings  https://savannah.gnu.org/bugs/?59820  

From there I reached to this discourse topic:  
https://octave.discourse.group/t/visibility-of-symbols-in-octave-libraries

Previously I used to think I could use all headers that shipped with Octave to develop packages/stand-alone programs. However I currently is noticed that only those functions and classes that are explicitly tagged with macros like OCTARRAY_API and  OCTINTERP_API are parts of the official interface to oct API. With the recent decision all symbols, other than the tagged symbols, of the Octave core libraries are made hidden (using a gcc capability). Therefore it is very difficult and painful to develop packages that are relied on those non tagged functions, if it is not impossible! The workaround may be including Octave source codes in the packages or fetch them from the repository when building the packages. However the workaround may fail because the linker may refer to fake symbols in the core dlls and refuse to using the compiled sources.
All package maintainer should check the package sources line by line to find those abandoned features, otherwise the packages compiles successfully but in the runtime may encounter segfault.
I also have found some buggy features. Consider this example:

// A.h
struct A
{
  A();
};

//B.h
struct OCTINTERP_API B
{
  B()
  {}

  void func (const A& a = A())
  {}
};

I have defined two classes "A" and "B" that one of them , "B", is a part of public API and the other, "A", isn't. The constructor of "A" will be defined in "A.cpp". However "B" is using "A" from its member function. Calling "func ()" results in segfault because it is using "A" that isn't a part of API. I have seen such classes in Octave source tree. Even "B" is a part of the public API it won't be usable at all.

There are possibly some issues related to import libraries that needs further checks.

Anonymous
Mon 17 Jan 2022 08:42:35 AM UTC, comment #1: 

With the information given, I cannot crash Octave.

I saved the given code in a file "params.cc" on MS Windows 10 (21H2), and using Octave 6.4.0, 7.0.90, 7.0.91 (each w64), I get:

>> mkoctfile params.cc
>> params
ans = 1

The code itself also does not look suspicious, even though the code digs deep into Octave internals.

Is the oct file recompiled for each used Octave version?  There is no perfect binary compatibility between releases (even minor ones).

Kai Torben Ohlhus <siko1056>
Project Member
Fri 14 Jan 2022 09:38:29 AM UTC, original submission:  

A segfault appeared when running a .oct file. I reduced the problem to a minimal example:

#include <octave/oct.h>
#include <octave/pt-all.h>

DEFUN_DLD (params, args, nargout,
           "segfault in user fcn")
{
    octave::tree_parameter_list *lst = new octave::tree_parameter_list(octave::tree_parameter_list::in);

    octave_user_function *fcn = new octave_user_function ();

    fcn->define_ret_list (lst);

    octave::tree_parameter_list *ret_list = fcn->return_list ();

    bool emp = ret_list->empty ();

    return octave_value(emp);
}

Simply I created an empty parameter list then set it as the return list of an empty user function and get it back via "return_list()" method of the "octave_user_function". Now calling any methods of the returned parameter list results in segfault. Segfault appeared here:

++
bool emp = ret_list->empty ();
--

The above code runs without error on Octave 6.3.0.
Note that the following code runs without any problem in 7.0.90:

    octave::tree_parameter_list *lst = new octave::tree_parameter_list(octave::tree_parameter_list::in);
    bool emp = lst->empty ();

The parameter list first must be saved into a user function and be retrieved back to reproduce the segfault.
Is may be a bug in GCC or a bug in Octave config and build system. Other API functions also may be affected.

Anonymous

 

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

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by siko1056 (Posted a comment)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-01-17 mmuetzel StatusNeed Info => Confirmed
    2022-01-17 siko1056 StatusNone => Need Info
        Summarysegfault in oct interface => segfault using tree_parameter_list in oct file

    Back to the top


    Powered by Savane 3.7