More frequent minor releases?

The time between Octave 5.1 and Octave 5.2 was exceptionally long. Among other things, that led to the situation where we closed quite a few reports as duplicates pointing people to the next minor release at an uncertain time in the (then) future which would contain a fix for the reported bugs.

I believe it was good to follow Octave 6.1 with Octave 6.2 in a “timely manner” after a few months.

There are already quite a few changes on the stable branch since Octave 6.2. (I counted 42.) Some of those are “just” documentation updates. But others fix buffer overflows or use-after-free kind of issues.
Should we keep up with that pace and try to make a minor release approximately every 3-4 months.

I don’t know how much manual effort each release entails. And I fear that this might take away developer time (mainly @jwe’s) that might be better spent for fixing bugs or developing new features.

On the other hand, the release process might be quite straight forward. Maybe the continuous builds run by @jwe and @siko1056 are helping. But I can’t judge.

If we’d like to follow a 3-4 months minor release period, an Octave 6.3 could be made in a few weeks.

What do you think?

I’m in favor of making more regular releases and agree that it is time for another minor release.

The time between Octave 5 and 6 was also much too long and I take full responsibility for that because of the huge amount of time it took to rewrite/refactor major parts of the interpreter to better support handles to nested functions.

In the absence of issues like we had for Octave 6, I think major releases once per year followed by 2-3 minor releases every 2-3 months seems like a reasonable frequency. So we could aim for a major release in January followed by minor releases in March/April, June/July, and September/October (if necessary). The version 6 release is shifted from that schedule because we released 6.1 in November 2020, not January of this year.

I don’t mind being “in charge” of the release process and have no plans to stop working on Octave any time soon, but we need to make sure that is documented and that it is possible (and easy) for others to step in if needed. Also, with all the things that need to be done for a release, it is no longer easy or reasonable for one person to do the entire job and even though we have checklist(s) it is easy to miss a few things. For the next minor release, I will put a copy of the checklist on the wiki and we can check off items as they are completed.

Are there any bug reports that remain to be addressed before the 6.3 release?

1 Like

I’m seeing the following reports for Octave 6 are marked as segfaults (or similar):

I’m not sure if any of those should be blocking a release. But it might still be worthwhile to check if there are easy fixes.

The following reports for Octave 6 are marked as regressions:

One is for a feature that is no longer actively maintained (gnuplot). Another one is an old regression. Imho, they shouldn’t block the release.
It might be nice if bug #60531 could be fixed before the release.

Many thanks to @siko1056 and his Savannah Bugs and Patches site that made collecting these reports a lot easier.

What I wrote is just a quick, personal rating.
I don’t claim that this is an exhaustive list. Please, add other reports you’d like to nominate.

1 Like

Thanks @mmuetzel . Your bugs as dynamic list:

1 Like

Another two bugs that might be worth fixing on stable before a release:

This one is pretty easy. Because this doesn’t need to be high performance code (it is only in the debug path) it would be fine to solve this by just copying over the necessary frames in to retval.


I just (5/14/21) checked in a fix for this bug. I think we could go ahead with next steps for release.

These should be fixed as they affect building Octave. They are not hard, I just don’t think they backported cleanly and that meant there would need to be some programmer time figuring out how to resolve the conflicts.

I created a release checklist page on the wiki. Please update as needed. We can use this page as the template for minor releases in the future.

https://wiki.octave.org/6.3_Release_Checklist

I don’t think we should update gnulib or create new translation files for minor releases. I marked those activities as done (with strikethrough), but maybe they should be removed from the template itself.

I ran the grammarcheck and spellcheck scripts on the stable branch and crossed off those activities. The only thing left in the documentation category is updating the NEWS file (if there is anything). In general, I wouldn’t think we would be generating items for the NEWS file in a bug-fixing release.

I would be fine with going ahead now and making a 6.3 release without fixing any of these remaining bugs. The dbstack bug could be fixed because it would be easy, but doesn’t have to be.

I updated the wiki page to just note that updates to gnulib and translations are not normally done for bug-fixing releases.

For the NEWS file, we usually include a list of bugs that were fixed. This info can be extracted from the bug tracker just before the release.

Thanks to this question on the help mailing list, I just noticed that (some? all?) oct files built with version 6.2 cause a segmentation fault when called in version 6.2.1 on the stable branch. This seems like a very bad regression.

I know that we always require oct files and packages to be rebuilt when upgrading from one major release to the next, but not bug fix releases.

$ octave-6.2.0 --silent
>> pkg install -forge control
>> pkg load control
>> s = tf('s')

Transfer function 's' from input 'u1' to output ...

 y1:  s

Continuous-time model.
>> quit

$ ./run-octave --silent
>> version -hgid
ans = 68d64190da65
>> pkg load control
>> s = tf('s')
fatal: caught signal Segmentation fault -- stopping myself...
Segmentation fault (core dumped)
1 Like

I haven’t bisected. Only looked through the changes on the stable branch.
It could be that these changes are API incompatible:

I did it backwards (install on a recent hg and try to run on 6.2.0):

octave:1> pkg load control
octave:2> s = tf('s')
error: Invalid call to __lti_input_idx__.  Correct usage is:

 -- Loadable Function: [MAT_IDX, OPT_IDX, OBJ_FLG] = __lti_input_idx__
          (ARGS)
error: called from
    print_usage at line 98 column 5
    tf at line 211 column 31
    tf at line 197 column 11

Recompiled w/ debug symbols. Loading 6.2.0 package in 6.2.1:

octave:1> pkg load control
octave:2> s = tf('s')

Thread 7 "QThread" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffeb8d0e700 (LWP 2030512)]
0x00007ffff42f502a in octave_base_matrix<Cell>::matrix_type (this=0x0, _typ=...)
    at ../libinterp/octave-value/ov-base-mat.cc:289

<...deleted...>
Thread 7 (Thread 0x7ffeb8d0e700 (LWP 2030512)):
#0  0x00007ffff42f502a in octave_base_matrix<Cell>::matrix_type(MatrixType const&) const (this=0x0, _typ=...)
    at ../libinterp/octave-value/ov-base-mat.cc:289
#1  0x00007ffeb6e65aa1 in octave_value::is_defined() const (this=0x6020002381f0)
    at /usr/local/include/octave-6.2.0/octave/../octave/ov.h:552
#2  0x00007ffeb6e64cb9 in F__lti_input_idx__(octave_value_list const&, int) (args=...) at lti_input_idx.cc:64
#3  0x00007ffff42dd8b4 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) (this=0x612000206a40, 
    tw=..., nargout=3, args=...) at ../libinterp/octave-value/ov-builtin.cc:59
#4  0x00007ffff43d0dea in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&)
    (this=0x612000206a40, tw=..., nargout=3, args=...) at ../libinterp/octave-value/ov-fcn.cc:57
#5  0x00007ffff474dcc3 in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) (this=0x60e0000f8ae0, tw=..., nargout=3)
    at ../libinterp/parse-tree/pt-idx.cc:402
#6  0x00007ffff46d2d4c in octave::tree_multi_assignment::evaluate_n(octave::tree_evaluator&, int) (this=0x606000a1ae60, tw=...)
    at ../libinterp/parse-tree/pt-assign.cc:201
#7  0x00007ffff46d68b2 in octave::tree_multi_assignment::evaluate(octave::tree_evaluator&, int) (this=0x606000a1ae60, tw=..., nargout=0)
    at ../libinterp/parse-tree/pt-assign.h:156
#8  0x00007ffff4707c00 in octave::tree_evaluator::visit_statement(octave::tree_statement&) (this=0x6220000206a0, stmt=...)
    at ../libinterp/parse-tree/pt-eval.cc:3039
#9  0x00007ffff476dfa7 in octave::tree_statement::accept(octave::tree_walker&) (this=0x6040009fea10, tw=...)
    at ../libinterp/parse-tree/pt-stmt.h:124
#10 0x00007ffff47087bd in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) (this=0x6220000206a0, lst=...)
    at ../libinterp/parse-tree/pt-eval.cc:3124
#11 0x00007ffff42150e9 in octave::tree_statement_list::accept(octave::tree_walker&) (this=0x6040009fc610, tw=...)
    at ../libinterp/parse-tree/pt-stmt.h:201
#12 0x00007ffff4705b10 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&)
    (this=0x6220000206a0, user_function=..., nargout=1, xargs=...) at ../libinterp/parse-tree/pt-eval.cc:2778
#13 0x00007ffff44d07a9 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&)
    (this=0x61300007c980, tw=..., nargout=1, args=...) at ../libinterp/octave-value/ov-usr-fcn.cc:503
#14 0x00007ffff44d0618 in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&)
    (this=0x61300007c980, tw=..., nargout=1, args=...) at ../libinterp/octave-value/ov-usr-fcn.cc:496
#15 0x00007ffff474dcc3 in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) (this=0x60e0000f8220, tw=..., nargout=1)
    at ../libinterp/parse-tree/pt-idx.cc:402
#16 0x00007ffff4753796 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) (this=0x60e0000f8220, tw=..., nargout=1)
    at ../libinterp/parse-tree/pt-idx.h:107
#17 0x00007ffff46d14bb in octave::tree_simple_assignment::evaluate(octave::tree_evaluator&, int) (this=0x606000a19000, tw=...)
    at ../libinterp/parse-tree/pt-assign.cc:101
#18 0x00007ffff4707c00 in octave::tree_evaluator::visit_statement(octave::tree_statement&) (this=0x6220000206a0, stmt=...)

<...deleted...>

In comment #12 of bug report #60237, I wrote:

I pushed a series of changes on stable to fix this problem for nested and anonymous functions:

octave: 0574c36a095e
octave: c74ff452e2bb
octave: 34d06c73b48d

These changesets make changes in public interfaces, which is something that we try to avoid during a stable release series. OTOH, they are important to make handles to nested and anonymous functions work properly. And since handles to nested functions were one of the big new features of Octave 6, I’m in favor of making this change in version 6 even if it causes some (small) backward compatibility issues. These interfaces are not something that typical users (even those who write .oct files) will encounter.

I didn’t think that these changes would cause segfaults like those reported here.

I’m open to suggestions, but without these changes, handles to nested functions are mostly broken. I couldn’t see any way to fix those problems without changing some interfaces.

IIUC, we usually don’t do that for minor releases. But if there is no other way to keep the API stable, should we bump the API version this time?
Would that avoid the segfault?

IMHO, if we are considering bumping the API version, we might as well bump the major version as well and call it version 7.1.0.

Is not it API vs ABI thing? I.e. API is the same but ABI has changed.

Just to add an example how other projects are handling ABI breakages within a major release cycle: IIUC, the LLVM devs are incrementing the second number in the version string to indicate ABI changes. They increment the third number for updates that keep the ABI stable.
After LLVM 11.0, they released LLVM 11.0.1 that was ABI compatible with LLVM 11.0.0. Additionally, they released LLVM 11.1.0 which was not ABI compatible with LLVM 11.0.0 (but restored ABI compatibility with LLVM 10). Otherwise, it contained the same fixes as LLVM 11.0.1:
LLVM 11.1 Released To Deal With ABI Breakage - Phoronix

That doesn’t really fit our version numbering scheme because we already use the second number for changes that (preferably?) are ABI compatible. But they still called it LLVM 11 even though LLVM 11.1.0 was not ABI compatible.
Also, I want to be clear that I’m not proposing that we should have two stable versions (one that keeps and another one that breaks the ABI).

If I read those changes correctly, new functions and members have been added to some classes (among others to the octave_value class). I’m not sure if that constitutes an API change.
But I’d guess that both the API and the ABI have changed on the stable branch since 6.2.0.