bugGNU Octave - Bugs: bug #64213, crash while using subsasgn with...

 
 

bug #64213: crash while using subsasgn with struct and multiple subs value

Submitter:  Dmitri A. Sergatskov <dasergatskov>
Submitted:  Thu 18 May 2023 03:32:59 PM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  8.3.0 Planned Release:  8.3.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 05 Aug 2023 01:36:59 PM UTC, comment #7: 

Using the motivating example from comment #1, I'm see this:

>> function o = nested_assignment(name_list, value)
    idx.type = ".";
    idx.subs = {};
    name_list_length = length (name_list);
    for i = 1:name_list_length
        idx.subs{i} = name_list{i};
    endfor
    o = struct ();
    subsasgn (o, idx, value);
endfunction
>> nested_assignment({"Vipul", "Cariappa", "N", "T"}, 3)
error: subsasgn: structure field names must be strings
error: called from
    nested_assignment at line 9 column 5
>> version -hgid
ans = e039114b8a1a
>>


Closing as fixed.

Markus Mützel <mmuetzel>
Group administrator
Sat 29 Jul 2023 11:43:17 AM UTC, comment #6: 

Forgot to include the function name in one of the error messages.
Added here:
https://hg.savannah.gnu.org/hgweb/octave/rev/e039114b8a1a

Markus Mützel <mmuetzel>
Group administrator
Fri 28 Jul 2023 04:45:04 PM UTC, comment #5: 

I pushed the change to the stable branch here:
https://hg.savannah.gnu.org/hgweb/octave/rev/ce1ae40de0f0

It seems to be working correctly here and I didn't notice adverse side effects while testing.
Let's see if the CI notices something for the Octave packages that are included in the tests.

Marking as ready for test.

Markus Mützel <mmuetzel>
Group administrator
Fri 28 Jul 2023 02:32:12 PM UTC, comment #4: 

Oops, typo. Meant to write: "I don't know why that shouldn't be ok [...]".

Markus Mützel <mmuetzel>
Group administrator
Fri 28 Jul 2023 02:31:07 PM UTC, comment #3: 

The attached patch fixes the crash for me.

It replaces a few `panic_if` by throwing an exception (using our `error` function). I don't know why that should be ok, given that these function already call the `error` function elsewhere.

I only tested on the default branch. But it might also work for the stable branch.

Tentatively marking as targeting Octave 8.3.0.



(file #54991)

Markus Mützel <mmuetzel>
Group administrator
Fri 28 Jul 2023 07:03:12 AM UTC, comment #2: 

If I understand the reproducer correctly, it is an elaborate way to write:

o = struct();
o.({"Vipul", "Cariappa", "N", "T"}) = 3


Indexing a structure with a cell array doesn't work. And the above syntax correctly displays an error message:

>> o = struct();
>> o.({"Vipul", "Cariappa", "N", "T"}) = 3
error: dynamic structure field names must be strings


I don't know what the original intent of that function is. But guessing from the function name, it might be something like the following:

nested_fields = {"Vipul", "Cariappa", "N", "T"};
idx = struct('type', '.', 'subs', nested_fields);

o = struct ();
o = subsasgn (o, idx, 3);


But I agree that Octave shouldn't crash but preferably emit an error message similar to the "simpler" syntax.

Reducing the reproducer:

nested_fields = {"Vipul", "Cariappa", "N", "T"};
idx = struct('type', '.', 'subs', {nested_fields});

o = struct ();
o = subsasgn (o, idx, 3);



Markus Mützel <mmuetzel>
Group administrator
Thu 18 May 2023 03:34:19 PM UTC, comment #1: 

Attached files got stripped off. Re-attaching.

Dmitri.
--


(file #54757, file #54758)

Dmitri A. Sergatskov <dasergatskov>
Thu 18 May 2023 03:32:59 PM UTC, original submission:  

See discussion at
https://octave.discourse.group/t/panic-impossible-state-reached-while-using-subsasgn-with-struct-and-multiple-subs-value/4494

The code (also attached)

function o = nested_assignment(name_list, value)
    idx.type = ".";
    idx.subs = {};

    name_list_length = length (name_list);

    for i = 1:name_list_length
        idx.subs{i} = name_list{i};
    endfor

    o = struct ();
    subsasgn (o, idx, value);
endfunction


crashes when called:

nested_assignment({"Vipul", "Cariappa", "N", "T"}, 3)


on 8.2.0 and the latest dev snapshot (28ef2991fb5a tip @

Backtrace (also attached):



(gdb) thread apply all bt

Thread 8 (Thread 0x7ffed5bff640 (LWP 250189) "QThread"):
#0  0x00007ffff1c55b0a in sigtimedwait () at /lib64/libc.so.6
#1  0x00007ffff1c5514c in sigwait () at /lib64/libc.so.6
#2  0x00007ffff43befea in signal_watcher(void*) (arg=0x7ffff75314a5 <octave::generic_sig_handler(int)>) at ../liboctave/wrappers/cxx-signal-helpers.cc:179
#3  0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#4  0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 7 (Thread 0x7ffed6734640 (LWP 250188) "QThread"):
#0  0x00007ffff1ca157c in __pthread_kill_implementation () at /lib64/libc.so.6
#1  0x00007ffff1c54d46 in raise () at /lib64/libc.so.6
#2  0x00007ffff1c287f3 in abort () at /lib64/libc.so.6
#3  0x00007ffff715ea1a in octave::error_system::vpanic(char const*, __va_list_tag*) (this=0x7ffec8008b48, fmt=0x7ffff75d29a0 "impossible state reached in file '%s' at line %d", args=0x7ffed6730df8) at ../libinterp/corefcn/error.cc:633
#4  0x00007ffff7161b16 in vpanic(char const*, __va_list_tag*) (fmt=0x7ffff75d29a0 "impossible state reached in file '%s' at line %d", args=0x7ffed6730df8) at ../libinterp/corefcn/error.cc:1102
#5  0x00007ffff7161bbd in panic(char const*, ...) (fmt=0x7ffff75d29a0 "impossible state reached in file '%s' at line %d") at ../libinterp/corefcn/error.cc:1111
#6  0x00007ffff6e43797 in panic_if(bool) (cond=true) at ../libinterp/corefcn/error.h:507
#7  0x00007ffff6f067fa in octave_scalar_struct::subsasgn(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::list<octave_value_list, std::allocator<octave_value_list> > const&, octave_value const&) (this=0x7ffec847b1d0, type=".", idx=std::__cxx11::list = {...}, rhs=...) at ../libinterp/octave-value/ov-struct.cc:1234
#8  0x00007ffff6f1eda7 in octave_value::subsasgn(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::list<octave_value_list, std::allocator<octave_value_list> > const&, octave_value const&) (this=0x7ffed67310e8, type=".", idx=std::__cxx11::list = {...}, rhs=...) at ../libinterp/octave-value/ov.cc:1510
#9  0x00007ffff6f2e4da in octave::Fsubsasgn(octave_value_list const&, int) (args=...) at ../libinterp/octave-value/ov.cc:3749
#10 0x00007ffff6ffc3d6 in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) (this=0x7ffec8008c38, builtin_function=..., nargout=0, args=...) at ../libinterp/parse-tree/pt-eval.cc:3362
#11 0x00007ffff6e54927 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) (this=0x7ffec8080b90, tw=..., nargout=0, args=...) at ../libinterp/octave-value/ov-builtin.cc:49
#12 0x00007ffff6eb8140 in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) (this=0x7ffec8080b90, tw=..., nargout=0, args=...) at ../libinterp/octave-value/ov-fcn.cc:57
#13 0x00007ffff701e05d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) (this=0x7ffec82b3040, tw=..., nargout=0) at ../libinterp/parse-tree/pt-idx.cc:427
#14 0x00007ffff7020b97 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) (this=0x7ffec82b3040, tw=..., nargout=0) at ../libinterp/parse-tree/pt-idx.h:104
#15 0x00007ffff6ffdf45 in octave::tree_evaluator::visit_statement(octave::tree_statement&) (this=0x7ffec8008c38, stmt=...) at ../libinterp/parse-tree/pt-eval.cc:3863
#16 0x00007ffff702a942 in octave::tree_statement::accept(octave::tree_walker&) (this=0x7ffec82b3390, tw=...) at ../libinterp/parse-tree/pt-stmt.h:120
#17 0x00007ffff6ffe41f in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (this=0x7ffec8008c38, lst=...) at ../libinterp/parse-tree/pt-eval.cc:3948
#18 0x00007ffff6e0450c in octave::tree_statement_list::accept(octave::tree_walker&) (this=0x7ffec8474df0, tw=...) at ../libinterp/parse-tree/pt-stmt.h:193
#19 0x00007ffff6ffd065 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) (this=0x7ffec8008c38, user_function=..., nargout=0, xargs=...) at ../libinterp/parse-tree/pt-eval.cc:3587
#20 0x00007ffff6f13a3b in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) (this=0x7ffec824d5a0, tw=..., nargout=0, args=...) at ../libinterp/octave-value/ov-usr-fcn.cc:495
#21 0x00007ffff6f139b4 in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) (this=0x7ffec824d5a0, tw=..., nargout=0, args=...) at ../libinterp/octave-value/ov-usr-fcn.cc:488
#22 0x00007ffff701e05d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) (this=0x7ffec8306dc0, tw=..., nargout=0) at ../libinterp/parse-tree/pt-idx.cc:427
#23 0x00007ffff7020b97 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) (this=0x7ffec8306dc0, tw=..., nargout=0) at ../libinterp/parse-tree/pt-idx.h:104
#24 0x00007ffff6ffdf45 in octave::tree_evaluator::visit_statement(octave::tree_statement&) (this=0x7ffec8008c38, stmt=...) at ../libinterp/parse-tree/pt-eval.cc:3863
#25 0x00007ffff702a942 in octave::tree_statement::accept(octave::tree_walker&) (this=0x7ffec82116d0, tw=...) at ../libinterp/parse-tree/pt-stmt.h:120
#26 0x00007ffff6ffe41f in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (this=0x7ffec8008c38, lst=...) at ../libinterp/parse-tree/pt-eval.cc:3948
#27 0x00007ffff6e0450c in octave::tree_statement_list::accept(octave::tree_walker&) (this=0x7ffec849ced0, tw=...) at ../libinterp/parse-tree/pt-stmt.h:193
#28 0x00007ffff6ff358c in octave::tree_evaluator::eval(std::shared_ptr<octave::tree_statement_list>&, bool) (this=0x7ffec8008c38, stmt_list=std::shared_ptr<octave::tree_statement_list> (use count 2, weak count 0) = {...}, interactive=true) at ../libinterp/parse-tree/pt-eval.cc:985
#29 0x00007ffff6ff2c06 in octave::tree_evaluator::repl() (this=0x7ffec8008c38) at ../libinterp/parse-tree/pt-eval.cc:804
#30 0x00007ffff73cb4c5 in octave::interpreter::main_loop() (this=0x7ffec8008a40) at ../libinterp/corefcn/interpreter.cc:1315
#31 0x00007ffff73c5f1a in octave::interpreter::execute() (this=0x7ffec8008a40) at ../libinterp/corefcn/interpreter.cc:883
#32 0x00007ffff7bef4b0 in octave::interpreter_qobject::execute() (this=0x71a530) at ../libgui/src/interpreter-qobject.cc:87
#33 0x00007ffff7cfcdb2 in octave::interpreter_qobject::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x71a530, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0x9bd2c8) at libgui/src/moc-interpreter-qobject.cc:88
#34 0x00007ffff4ed2cd9 in QObject::event(QEvent*) () at /lib64/libQt5Core.so.5
#35 0x00007ffff5baf533 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5
#36 0x00007ffff7c6152d in octave::octave_qapplication::notify(QObject*, QEvent*) (this=0x4a7110, receiver=0x71a530, ev=0x9bd280) at ../libgui/src/octave-qobject.cc:148
#37 0x00007ffff4ea7938 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt5Core.so.5
#38 0x00007ffff4eaae86 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /lib64/libQt5Core.so.5
#39 0x00007ffff4ef9d07 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () at /lib64/libQt5Core.so.5
#40 0x00007ffff0f2fe2f in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
--Type <RET> for more, q to quit, c to continue without paging--c
#41 0x00007ffff0f84508 in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#42 0x00007ffff0f2d5f3 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#43 0x00007ffff4ef97a8 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#44 0x00007ffff4ea6342 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#45 0x00007ffff4ce89aa in QThread::exec() () at /lib64/libQt5Core.so.5
#46 0x00007ffff4ce9c8d in QThreadPrivate::start(void*) () at /lib64/libQt5Core.so.5
#47 0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#48 0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 5 (Thread 0x7ffed7011640 (LWP 250182) "gdbus"):
#0  0x00007ffff1d4296f in poll () at /lib64/libc.so.6
#1  0x00007ffff0f8449c in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#2  0x00007ffff0f2f483 in g_main_loop_run () at /lib64/libglib-2.0.so.0
#3  0x00007ffedc1eae1a in gdbus_shared_thread_func.lto_priv () at /lib64/libgio-2.0.so.0
#4  0x00007ffff0f5e582 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#5  0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#6  0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 4 (Thread 0x7ffed7812640 (LWP 250181) "gmain"):
#0  0x00007ffff1d4296f in poll () at /lib64/libc.so.6
#1  0x00007ffff0f8449c in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#2  0x00007ffff0f2d5f3 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#3  0x00007ffff0f2d641 in glib_worker_main () at /lib64/libglib-2.0.so.0
#4  0x00007ffff0f5e582 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#5  0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#6  0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 3 (Thread 0x7ffedd515640 (LWP 250167) "QXcbEventQueue"):
#0  0x00007ffff1d4296f in poll () at /lib64/libc.so.6
#1  0x00007ffff1a75f42 in poll (__timeout=-1, __nfds=1, __fds=0x7ffedd514108) at /usr/include/bits/poll2.h:48
#2  _xcb_conn_wait (c=0x4bed80, vector=0x0, count=0x0, cond=<optimized out>) at /usr/src/debug/libxcb-1.13.1-9.el9.x86_64/src/xcb_conn.c:479
#3  0x00007ffff1a7790c in _xcb_conn_wait (count=0x0, vector=0x0, cond=0x4bedc0, c=0x4bed80) at /usr/src/debug/libxcb-1.13.1-9.el9.x86_64/src/xcb_conn.c:445
#4  xcb_wait_for_event (c=0x4bed80) at /usr/src/debug/libxcb-1.13.1-9.el9.x86_64/src/xcb_in.c:697
#5  0x00007fffee98f407 in QXcbEventQueue::run() () at /lib64/libQt5XcbQpa.so.5
#6  0x00007ffff4ce9c8d in QThreadPrivate::start(void*) () at /lib64/libQt5Core.so.5
#7  0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#8  0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 2 (Thread 0x7ffeddd16640 (LWP 250166) "QDBusConnection"):
#0  0x00007ffff1d4296f in poll () at /lib64/libc.so.6
#1  0x00007ffff0f8449c in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#2  0x00007ffff0f2d5f3 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#3  0x00007ffff4ef97a8 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#4  0x00007ffff4ea6342 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#5  0x00007ffff4ce89aa in QThread::exec() () at /lib64/libQt5Core.so.5
#6  0x00007ffeddd85b8b in QDBusConnectionManager::run() () at /lib64/libQt5DBus.so.5
#7  0x00007ffff4ce9c8d in QThreadPrivate::start(void*) () at /lib64/libQt5Core.so.5
#8  0x00007ffff1c9f832 in start_thread () at /lib64/libc.so.6
#9  0x00007ffff1c3f450 in clone3 () at /lib64/libc.so.6

Thread 1 (Thread 0x7ffff1a3a300 (LWP 250095) "octave-gui"):
#0  0x00007ffff1d4296f in poll () at /lib64/libc.so.6
#1  0x00007ffff0f8449c in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#2  0x00007ffff0f2d5f3 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#3  0x00007ffff4ef97a8 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#4  0x00007ffff4ea6342 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt5Core.so.5
#5  0x00007ffff4eae874 in QCoreApplication::exec() () at /lib64/libQt5Core.so.5
#6  0x00007ffff7c62e6c in octave::base_qobject::exec() (this=0x7fffffffbfa0) at ../libgui/src/octave-qobject.cc:423
#7  0x00007ffff7c77563 in octave::qt_application::execute() (this=0x7fffffffc0f0) at ../libgui/src/qt-application.cc:102
#8  0x0000000000402767 in main(int, char**) (argc=8, argv=0x7fffffffc4f8) at ../src/main-gui.cc:150
(gdb)


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #54991:  bug64213-subsasgn-invalid-fieldnames.patch added by mmuetzel (5KiB - application/octet-stream)
file #54757:  nested_assignment.m added by dasergatskov (274B - text/x-objcsrc)
file #54758:  subassign_crash_bt.txt.gz added by dasergatskov (3KiB - application/gzip)

 

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 dasergatskov (Submitted the item)
  •  

    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.

     

    Follow 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-08-05 mmuetzel StatusReady For Test Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 8.3.0
    2023-07-28 mmuetzel StatusPatch Submitted Ready For Test
    2023-07-28 mmuetzel Attached File- Added bug64213-subsasgn-invalid-fieldnames.patch, #54991
        StatusConfirmed Patch Submitted
        Planned ReleaseNone 8.3.0
    2023-07-28 mmuetzel Item GroupNone Segfault, Bus Error, etc.
        StatusNone Confirmed
    2023-05-18 dasergatskov Attached File- Added nested_assignment.m, #54757
        Attached File- Added subassign_crash_bt.txt.gz, #54758

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code