bugGNU Octave - Bugs: bug #44485, GUI: File | Exit from main menu...

 
 

bug #44485: GUI: File | Exit from main menu doesn't work when Octave is busy

Submitter:  Philip Nienhuis <philipnienhuis>
Submitted:  Sun 08 Mar 2015 02:19:10 PM UTC
   
 
Category:  GUI Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Other
Status:  Confirmed Assigned to:  None
Originator Name:  Philip Nienhuis Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 28 May 2020 01:25:11 AM UTC, comment #52: 

Since this changeset:

http://hg.savannah.gnu.org/hgweb/octave/rev/c5c11b07598a

it has not been possible to interrupt long-running compiled functions.  So another approach will be needed to handle those.  But it should be possible to interrupt any interpreted code so exiting while Octave is executing interpreted code should be possible.

If we want to fix the problem of interrupting long-running compiled code safely, then I think the best bet might be to create a separate thread to evaluate that code so that an interrupt can simply cancel the thread.

John W. Eaton <jwe>
Group administrator
Thu 28 May 2020 12:53:29 AM UTC, comment #51: 

Still an issue in Octave 6.x (bug #58454).  Tested example of comment #0 with HG ID https://hg.savannah.gnu.org/hgweb/octave/rev/2b52e473b6ef (stable).

Kai Torben Ohlhus <siko1056>
Group Member
Fri 23 Dec 2016 09:09:29 PM UTC, comment #50: 

I think this issue is still open in Octave 4.2.0.

(See https://savannah.gnu.org/bugs/index.php?45366#comment12 )

Hartmut <hardy>
Fri 14 Aug 2015 09:08:54 PM UTC, comment #49: 

The patch from comment #44 doesn't apply cleanly anymore,
"Hunk #1 FAILED at 91"
The code for column sorting has changed too much I'm afraid, much more than I can deal with (my C++ proficiency is a bit meager).

Could you (when you have time) please update this patch?

Thanks

Philip Nienhuis <philipnienhuis>
Group Member
Sun 19 Jul 2015 08:32:31 AM UTC, comment #48: 

Have a nice vacation.  (I'm not sure why the unstable build-tool mods are being done in a the development branch.)

Dan Sebald <sebald>
Fri 17 Jul 2015 09:35:23 AM UTC, comment #47: 

I got hit by the recent changes in the build system and ran out of time.
Maybe maybe I can have another try but we're off on vacation very soon. If not it'll be mid-August before I can report back.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 15 Jul 2015 05:05:07 AM UTC, comment #46: 

That's fine.  Take your time...  Yes, the recent patch needs to be applied after the patch that fixes the destructors.  Just "rollback" to that previous patch.  ("hg log" should show


description:
Save settings in Qt convention, delete all children in destructors (bug #45366)


prior to applying.)

Dan Sebald <sebald>
Tue 14 Jul 2015 07:30:41 PM UTC, comment #45: 

Sorry for the late reply, I'm trying to finish other urgent or long-pending stuff before my vacation and I got little time ATM anyway.

Does your patch from comment #44 need to be applied after that of https://savannah.gnu.org/bugs/index.php?45366 ?

Philip Nienhuis <philipnienhuis>
Group Member
Wed 08 Jul 2015 09:08:00 PM UTC, comment #44: 

I really couldn't find much on how to suppress Windows from creating a message dialog.  I gather the message said something about improperly terminating unexpectedly.  In any case, I think once we get to the point of terminating the interpreter (which is unadvised except for the last resort, what we are using it for) that all bets are off on how the program and system will work.  The Qt discussion lists mention how terminating can freeze up resource unexpected such as mutexes and so on.  The proper terminate/abort approach is discussed here:

https://forum.qt.io/topic/20539/what-is-the-correct-way-to-stop-qthread

but it would require a small change to the worker thread which I don't want to make for this solution nor ask any of the more maintainer oriented contributors to make.  The ability to interrupt is close enough I suppose.

So I've attached an updated changeset that I think and hope is a solution that will do and not produce messages or corrupted settings files.

1) I changed the final 2 second timeout for cleanup to 5 seconds.  Rarely will cleanup take five seconds, I'm hoping, so the last ditch terminate should be less likely now.

2) I changed the exit under the terminate condition from


  exit_app (6);


to


  exit_app (0);


That may not make a difference, but maybe that will prevent some type of Windows or Linux dialog popup window.

3) And the last one is to remove what may have been the source of problems in the


  // Three interrupts might cause interpreter to exit.
  _octave_qt_link->terminal_interrupt ();
  _octave_qt_link->terminal_interrupt ();
  _octave_qt_link->terminal_interrupt ();


I'm thinking now that was probably the wrong thing to do.  If this code hunk is reached because of the cleanup timeout, it is causing an abort and that may be what brings about the Windows message.  It might be the source of the source of the corrupted settings file too because right after this code hunk it might be like a race condition where the GUI code continues on and does some QSettings sorts of things while the worker does and abort.  Not sure, but unpredicable situation.

So give the attached changeset a try.  Thanks.

(file #34396)

Dan Sebald <sebald>
Mon 06 Jul 2015 07:45:24 AM UTC, comment #43: 

You've characterized things pretty well now, thanks.  I think if we can just figure out how to cleanly kill the thread so that Windows doesn't complain, then we are close.  The other issue with qt-settings could maybe be separate.  The time to wait seems like a question.  Maybe rather than wait 2 seconds, it could be changed to 4 or 5 seconds.  Here's the code hunk that was applied and should exist in the file main_window.cc:


+void
+main_window::force_exit_app (bool closenow)
+{
+  if (! closenow)
+    return;
+
+  // If confirmed, do not allow shutdown sequence again.  Doing
+  // so would mean something is wrong with the core's exit
+  // method and could lead to indefinite loop.
+  _closing = true;
+
+  // First interrupt will stop a process, so attempt exit.
+  _octave_qt_link->terminal_interrupt ();
+  octave_cmd_exec *cmd = new octave_cmd_exec ("exit");
+  queue_command (cmd);
+  _exit_in_queue = true;
+
+  // Give the core/worker two seconds to wrap up.
+  QTimer *timer = new QTimer ();
+  connect (timer, SIGNAL (timeout ()), this, SLOT (terminate_and_exit ()));
+  timer->setSingleShot (true);
+  timer->start (2000);
+}


Notice at the very end of the routine is 2000, the number of milliseconds.  If you want to experiment, you could change that to 10000 seconds and see how prevalent the popup warning is.

I too thought I had seen the corrupted qt-settings file upon testing.  But I didn't think anything of it because I was in the middle of debugging.  The only way I can think of that happening is if a qSettings object is writing the settings at the instant a process is ended.  But that should live in the GUI space, which supposedly is not the thread being killed.  Anyway, this one I can probably think through and figure out what the issue is.

Dan Sebald <sebald>
Sun 05 Jul 2015 09:19:19 AM UTC, comment #42: 

I wouldn't mind the performance differences between Windows and Linux that much. Rik and I did some tests a while back and arrived at the same results. But then I hadn't thought of equally optimimized libraries - on Linux Octave uses the distro libs, on Windows Octave uses (I suppose) highly optimized cross-built libs and OpenBlas. When I have some time I'll make an mxe native build on Linux to be able to compare a bit better.

On topic:
I hadn't thought of clean-up time,good suggestion! Indeed, before all 4 cores are invoked after submitting the eig() command it takes a few seconds and assigning all that RAM also takes time.

OK new tests:
=============

1th run:
--------
pause (20)
File | Exit, Force Exit:  clean shutdown, no zombie process, but qt-settings got fubarred completely.

2nd run:
--------
<changed some screen layout from the restored qt-settings backup>
pause (20)
Ends cleanly. Following octave-gui.exe in Task Manager I see that after disappearing from screen, the process hangs around 1 second or so (cleaning up?)

3rd run:
--------
pause (30)
<qt-settings in 2nd run hasn't been changed => clean exit apparently doesn't touch qt-settings>
Didn't end cleanly: got Windows pop-up

4th run:
--------
<qt-settings still hadn't been touched in run 3, it seems>
Ended clean

5th run:
--------
no clean end

:
etc

I also tried again with [V, D] = eigs (rand (1e4)); - ended cleanly.

Conclusions:
============
- About half of the tries (in the 10 attempts reported here) end in what Windows thinks is a crash, the other half exits cleanly

- I see no difference between eigs(1e4) and pause (20)

- qt-settings is only rarely affected. Until now, with the previous report included + many many forced exits with the previous patches, I've only hit a fubarred qt-settings twice (and there's bug #45459 that perhaps is related)

- In Task Manager I always see a process "FMAPP.exe" [*] appear for 4-5 seconds whe the Forced Exit popup window appears. It is related to my Lenovo laptop's audio system, so that triggered me to wonder if it pops up in the course of ending Octave's audio system? and is Octave's audio system shut down gracefully?

- This time I didn't note zombie octave-gui.exe processes but I did find a zombie process "conhost.exe" - it must have been started through Octave (conhost.exe is a component of the Windows process that runs the terminal)

What I could do is put the binary installer in my dropbox that other Windows users can try it out as well. My dropbox upload is very slow however (usually takes overnight). Anyway would this help?

Philip Nienhuis <philipnienhuis>
Group Member
Sat 04 Jul 2015 05:18:09 PM UTC, comment #41: 

The performance test is interesting, i.e., the fact that Windows is so much faster, but the two changesets affect code that is only exercised at exit.  I can't imagine that is taking very much longer.  BTW, I sort of prefer the performance test

start_time = cputime();
<process>
overall_time = cputime() - start_time()

The tic/toc are clock time and some aspects of Octave have a delay but really aren't using CPU.

Well, back to the exit problems on Windows.  At first things looked good; guess that's progress.  You'll have to characterize the behavior a little more and maybe it will give some ideas.  Try some things like:

1) Correlate the zombie occurrence with the Windows popup message.  Are there any times when there is a zombie and no message?  What is the Windows message exactly?

2) See if there are any problems with a task that doesn't use so much memory.  Try "pause(20)".  Maybe for the eigenvalues example the task of either interrupting or exiting takes so long to clean up memory that the allotted two second wait expires and the GUI kills the process and that is when a Windows popup appears.  It could be that this cleanup takes a random amount of time, sometimes finishing, sometimes not.

If the latter situation arises, we may need to figure out how to cleanly kill a process in Windows.  Perhaps that isn't being done exactly right.

Dan Sebald <sebald>
Sat 04 Jul 2015 04:32:42 PM UTC, comment #40: 

OK got some results.

1st run:
========

>> [V, D] = eigs (rand (1e4));  
>> ## tic/toc: takes ~146 seconds all 4 cores to complete
>> after a few seconds, File | Exit

=> after 3 seconds the popup; click Force Exit button => clean exit, no Windows popup. Nice!

2nd run:
========

>> tic; [V, D] = eigs (rand (1e4)); toc

Again after 3 seconds, Force Exit => Return to the prompt

>> Starting again with  [V, D] = eigs (rand (1e4));
>> after 3 seconds Exit, Force Exit: no clean exit (Windows program error popup)


3rd run:
========
[V, D] = eigs (rand (1e4));
Exit .... Force Exit
=>  no clean exit

4th run:  clean exit!
========

After running _run_test_suite_.m and again slecting File| Exit, Octave also exits "uncleanly". I don't know if this is related.

So all in all it is clearly better but still not a "reliably" "clean" exit. About half of the exits happen silently, the other half triggers operating system popups.
I wonder what could be hanging that triggers Windows. Open file handles? I see no core dump (octave-workspace) in the startup / working directory

Another thing I noted is that after several more attempts, in Task Manager (~ linux' "top") I saw 4 octave-gui.exe zombie processes taking ~4 GB of RAM (that RAM usage was what triggered me to find what process was taking so much RAM).


As to performance, I simply ran
tic; _run_test_suite_; toc
I tend to agree; 3 attempts with only 15 % not very reproducible results is not reliable yet. Would there be any reason for slowdown?
BTW on Windows, on the same box, tic; _run_test_suite_; toc  takes only ~5.7 secs versus ~16 - 19 secs. for Linux. I think the reason is probably less optimized distro libraries (I have Mageia-4). A better comparison would be an Octave Linux build made with mxe.

Philip Nienhuis <philipnienhuis>
Group Member
Sat 04 Jul 2015 07:22:36 AM UTC, comment #39: 

Performance degradation?  What test are you running that measures performance?  The only thing that should be affected is clean up and exit behavior--any processing should be unaffected.  Also, whatever you are measuring shows large enough deviation that the sample size you have is probably inconclusive.

Anyway, I'm looking forward to seeing if Windows works.  Hope so!  :-)

Dan Sebald <sebald>
Fri 03 Jul 2015 09:02:27 PM UTC, comment #38: 

OK, on Linux I've been able to test both patches. They seem to work fine; yet I see a little performance degradation:

Default:
Elapsed time is 16.635 seconds.
Elapsed time is 19.6625 seconds.
Elapsed time is 16.7454 seconds.


Default with patches:
Elapsed time is 19.7335 seconds
Elapsed time is 19.784 seconds
Elapsed time is 16.8324 seconds.
Elapsed time is 17.8482 seconds.


...but not very conclusive, admittedly.

I've yet to set up mxe-octave to cross-build for Windows. Hopefully this weekend or early next week I can report further progress.

Philip Nienhuis <philipnienhuis>
Group Member
Mon 29 Jun 2015 09:41:30 PM UTC, comment #37: 

Thanks, I'll try later this week  (I just upgraded my laptop with an SSD and have to re-install a lot of SW)

Philip Nienhuis <philipnienhuis>
Group Member
Mon 29 Jun 2015 07:08:27 AM UTC, comment #36: 

The old changeset patched with surprisingly few problems.  Attached is an update which is very much the same, so if this works for you on Windows, then we'll know that the destructor issue was likely the problem.

Remember you'll have to apply the patch here:

https://savannah.gnu.org/bugs/index.php?45366

first and then the attached patch.

(file #34337)

Dan Sebald <sebald>
Sat 27 Jun 2015 04:36:02 AM UTC, comment #35: 

The changeset for https://savannah.gnu.org/bugs/index.php?45366 comes before attempting the forced-exit.  We can wait for that changeset to be reviewed/applied, which is never a certainty.  Maybe later this weekend I will apply that changeset locally and build another changeset to attach here.  (The two changesets would need to be applied in order.)

Dan Sebald <sebald>
Sun 21 Jun 2015 06:51:43 PM UTC, comment #34: 

I managed to try the patch in
https://savannah.gnu.org/bugs/index.php?45366
in both Linux and Windows and AFAICS it works fine.

So, what next can I do?

Philip Nienhuis <philipnienhuis>
Group Member
Sun 21 Jun 2015 08:51:33 AM UTC, comment #33: 

Sure I will, but I have several other priorities the next days. I'll try to squeeze it somewhere in anyway :-)

Thanks for your perseverance with this code cleanup. You've surely turned a lot of stones along the way.


Philip Nienhuis <philipnienhuis>
Group Member
Sun 21 Jun 2015 08:15:14 AM UTC, comment #32: 

I've gone through the code and found the source of bugs at exit that were causing such a problem.  See

https://savannah.gnu.org/bugs/index.php?45366

It's a rather big changeset, and once that is integrated then I can return to this force-exit changeset.  (To combine into one patch would have been too much.)  If you'd like to test the patch that was placed at the above bug report for linux/windows, that would be helpful.

Dan Sebald <sebald>
Wed 17 Jun 2015 07:13:52 PM UTC, comment #31: 

Well, the Windows behavior certainly isn't acceptable.  After some digging, I think I see why this is happening.  The QSettings is instantiated and deleted by the worker thread.  Why that is, I don't know.  Doesn't seem very object oriented to have something in another thread handling the settings for what is in another thread.  I suppose the 1/2 second wait might not be long enough for the worker to finish cleanup and the thread happens to be deleted right in the middle of deleting that QSettings object.  (This can probably happen on Linux too, it just might be Windows is a little slower cleaning up.)  I'll bring this up on the discussion list.

The other issue is Windows displaying a message saying that Octave quit unexpectedly.  (Another indication that the worker was in fact deleted rather than finishing in the conventional way.)  It would be nice to figure out how to prevent Windows from displaying such a message in that circumstance in the cases where Octave is forcibly quit because it might be stuck.

Dan Sebald <sebald>
Wed 17 Jun 2015 11:51:04 AM UTC, comment #30: 

Thanks Dan for your continued efforts.

On Linux, "Force Exit" ends Octave more or less gracefully - no popups etc, no core dump.

On Windows I still get the "Octave has ended unexpectedly" Windows pop-up.  In addition the <HOME>\.config\qt-settings file got screwed up (didn't happen with the previous patch, but OK that may have been sheer luck the previous times)

Maybe we'd better give up for the time being to avoid this ending on Windows?

Philip Nienhuis <philipnienhuis>
Group Member
Tue 09 Jun 2015 02:28:52 AM UTC, comment #29: 

Here's a patch that I think is very near to what I've envisioned the closing process should be like.  It is a considerable rearrangement of the closing code which relies more on the connections of signals and slots.  The connections sort of act like a linked-list or serial processing of editor tabs.  One tab's save-continue signal is connected to the next tab's save-confirm slot.  If there is a cancellation, the tab doesn't emit the signal.

The proposed setup has more flexibility to shape the behavior of dialog boxes when closing and preventing things like a dialog opening multiple times.  So if there are any changes to be made, only small tweaks should be necessary.

Also, I did come across the long, verbose error message that I think you are seeing.  I'm not 100% certain, but I sort of isolated the cause as being related to the Qt Handles code.  If the interpreter thread is terminated, the message originates after the termination.  I think there is some kind of coordination going on between the interpreter and Qt Handles that is compromised when the interpreter quits prematurely.  I'd rather not dig into the Qt Handles code--at least not initially.  Judging from bug reports, there are certain parts of Qt use that aren't as robust as others and I suspect there will be changes somewhere in the future.  Nonetheless, the new scheme is set up so that terminating the interpreter is the last resort and the error message shouldn't appear so often if at all.

Here's a summary of changes:

1) Selecting "quit" or the upper-right close button will place an "exit" in the queue, as before.

2) A timer expires after 2 seconds if no shutdown is requested by the core and a dialog box is shown inquiring about "force exit", as before.

3) The existence of signal/slot connections determines if a dialog box is already present so that only one "force exit" dialog exists at a time.  (I.e., can no longer select "quit" twice quickly to create two dialog boxes asking to force quit.)

4) If the user selects force quit, the confirm-save process is started.  If that confirm-save process is complete before the interpreter asks to shutdown, the force-exit route is taken.

5) The force-exit route will issue a Cntrl-C, place "exit" in the queue again, and wait 0.5 seconds for a response.  Typically, in this scenario the interpreter will ask to shutdown at this point and another confirm-save will NOT be done.  Also, this is a clean exit so no error messages should appear.

6) If 5 still doesn't exit, that's an indication of the core really stuck/lost.  After half a second, the 3 Cntrl-C approach is attempted followed by terminating the interpreter.  This is a sort of last effort type of thing.  Here's when the error message might occur and if someone files a bug report for this I will look at the Qt Handles code.

7) And one last detail, if the user does a force-exit and is in the process of saving editor tabs when/if the interpreter gets around to requesting shutdown, the signal of completion is disconnected and reconnected instead to a slot that is the conventional response.  That makes sure that save-confirm isn't run twice simultaneously.


(file #34183)

Dan Sebald <sebald>
Wed 20 May 2015 04:54:44 PM UTC, comment #28: 

crash message happens upon GUI exit.
I think you hit it on the nose.
FTR on Linux I see no crash (or core dump).

Philip Nienhuis <philipnienhuis>
Group Member
Tue 19 May 2015 10:54:07 PM UTC, comment #27: 

Does this output appear anywhere:


panic: Interrupt -- stopping myself...


in the case of Windows?  My guess is not.  The three control-Cs probably aren't aborting the interpreter, so the change is effectively no different than previous and the crash message happens upon GUI exit.

I'll have to dig a little deeper.  Either find some graceful route for the interpreter to exit, or modify the exit signal message (from the GUI thread, so a semaphore is likely needed) so that the screen dump isn't done.  Tried the former quite a bit, so probably the latter will yield a solution.

Dan Sebald <sebald>
Tue 19 May 2015 09:58:09 PM UTC, comment #26: 

OK I tried the new patch.

I cannot assess much difference with the previous patch. On Windows there's still a hard crash, which IMO is unneeded as the user willingly kills Octave, isn't it.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 13 May 2015 04:32:07 AM UTC, comment #25: 

I'm checking here occasionally and still have this feature in the back of my mind, but I've very limited on time at the moment.

Here's a new patch with a new approach.  Rather than attempt to make QThread exit gracefully and/or try to change the Octave interpreter's signal handling (something I really don't want to change, no less before a release), let's try to use the interpreter's existing mechanism for aborting the program: Cntrl-C three times in a row.

In the attached patch I've done a forced exit by issuing four Cntrl-Cs in a row.  The first one won't contribute to "three-in-a-row" if it properly interrupts out of a process.  So, using the forced exit, I'm hoping the worst you see is the same as what is seen at the command line:


octave:1> inv(rand(10000))
^C^CPress Control-C again to abort.
^Cpanic: Interrupt -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete


I also changed the wait time to 2.0 seconds rather than 3.0.

I'm OK with the Cntrl-C abort approach, but I'm still not 100% sure of the flow is just right.  The one issue I see right now is if during forced exit and confirmation on open files the original "exit" gets processed and one "Cancel"s the exit via file-save, another immediate file-save confirmation will be attempted.

I will think about "double confirm" issue one a bit, but in mean time, please try this patch and see if it works better for you.

(file #33994)

Dan Sebald <sebald>
Mon 27 Apr 2015 10:17:41 AM UTC, comment #24: 

Of course "....value 6" would only be valid if 'File | Exit' interrupted some action by Octave (long calculation) or a function invoked by Octave (sleep(), system (...) ).

SIG gives:

>> SIG
ans =

  scalar structure containing the fields:

    ABRT =  22
    FPE =  8
    ILL =  4
    INT =  2
    SEGV =  11
    TERM =  15


didn't see HUP (which indeed gives reminiscences from the times of Hayes etc. :-) ).

Philip Nienhuis <philipnienhuis>
Group Member
Mon 27 Apr 2015 07:35:20 AM UTC, comment #23: 

Rather than a backtrace, the output would be "octave exited with value 6", meaning the program didn't exit in the conventional manner.  Guess I will aim for this behavior.

One can see the list of signals by typing "SIG" at the octave command line and can probably guess what many of the signals mean.  ABRT (6) means to abort the program.  INT (2) means interrupt.  There are even real archaic signals like HUP (1) which I think means "hang up"--computer comm links long ago were made by dialing into the system then placing the telephone receiver into a holder that would modulate tones to send data (at a really low baud rate).  To disconnect, hang up the telephone.

Dan Sebald <sebald>
Sun 26 Apr 2015 05:25:37 PM UTC, comment #22: 

Sorry that I may not be of much help as regards SIGABRT.
I do not know much about signal types on *nix; I can imagine Joe Average User doesn't either.
Can you explain what use SIGABRT has for a plain user? If it has advantages, I'd be all for it. But I just do not know.

While being a contributor with even push access, I'm less involved in lower level stuff but much more interested in the ergonomical side: error catching, meaningful actions if the unexpected (for users and developers) happens, that sort of thing.
From that POV I'm already quite content with your latest patch: IMO it does do what a user would expect (apart from the backtrace dump on Linux).
As to that backtrace: I haven't tried Octave from a desktop shortcut, but rather from the build dir with './run-octave &'. If users start the GUI from a shortcut, the backtrace may not be an issue anyway, isn't it?

Philip Nienhuis <philipnienhuis>
Group Member
Sun 26 Apr 2015 04:43:27 PM UTC, comment #21: 

How about a non-zero exit notification, i.e., SIGABRT?  Should we try for that?

Dan Sebald <sebald>
Sun 26 Apr 2015 08:54:59 AM UTC, comment #20: 

On Windows I also tried octave-gui from a cmd window and an MSYS terminal (rather than from a shortcut in the Star Menu or desktop). In both cases I saw no error messages at all when Octave disappeared from the screen.

It is on a quite fast PC (recent core i5 & SSD) so perhaps I indeed missed flashing error messages, who knows.

IMO a backtrace isn't very useful. After all the user knowingly does a Forced exit, isn't it? - her/his primary aim is to get out of Octave ASAP. It's an excessively long backtrace as well (on Linux).
If you can make it so that he backtrace isn't shown I think the aim of this bug report has been reached: File | Exit works as expected by the average user.

Philip Nienhuis <philipnienhuis>
Group Member
Sun 26 Apr 2015 02:36:50 AM UTC, comment #19: 

When disappeared without a trace, was that when there were no modified files in the editor?

Also, is it possible that the backtrace appeared in the GUI terminal window which disappeared so quickly it's barely noticeable?  When the GUI is launched, at first the OS terminal window receives the standard-error output, but then the GUI takes hold of that.  On shutdown, the GUI gives the stderr output back to the terminal window.  There could be a race condition between that output redirection and the Octave core worker processes aborting.  In one case the GUI might close before worker process displays a message, in another case after.

I think we should get a consensus on the expected behavior.  I'm alright with a backtrace output.  The shutdown is forced, after all, and the force operation is achieving what is wanted.  I'm a little reluctant to design it to issue an interrupt and then attempt exit again after the interrupt, because if the problem with the core isn't solved with an interrupt (i.e., it is truly stuck, as opposed to merely busy), then that strategy becomes and indefinite loop.

Dan Sebald <sebald>
Sat 25 Apr 2015 07:47:01 PM UTC, comment #18: 

On Windows the situation seems reversed as compared to Linux:

File | Exit while sleep(20) is running makes Octave crash (I get the Windows popup that "...program X has stopped working..." (read: crashed).

File | Exit during a 'inv(rand(10000))' instruction makes Octave disappear w/o a trace.

FYI on my Linux box Octave runs with reference BLAS, on Windows Octave with OpenBLAS.

Philip Nienhuis <philipnienhuis>
Group Member
Sat 25 Apr 2015 04:32:59 PM UTC, comment #17: 

(the verbatim copy in comment #16 is only a few lines; the start of the backtrace scrolled out of the Konsole terminal)

Philip Nienhuis <philipnienhuis>
Group Member
Sat 25 Apr 2015 04:31:37 PM UTC, comment #16: 

Thanks for the new patch.
It works at least on Linux (I will try Windows later).
Starting ./run-octave &, entering 'inv (rand (10000))' and then clicking File | Exit from the main menu, Octave waits for ~3 seconds, then gives a popup.
If I click "Force exit" in that popu, I get a sort of backtrace, a very long one:

:
/fontconfig/d62e99ef547d1d24cdb1bd22ec1a2976-le64.cache-47fd0972f4000-7fd0972f8000 r--s 00000000 08:05 4325750                    /var/cache/fontconfig/f6b893a7224233d96cb72fd88691c0b4-le64.cache-4
7fd0972f8000-7fd0972ff000 r--s 00000000 08:05 524991                     /usr/lib64/gconv/gconv-modules.cache
7fd0972ff000-7fd097301000 rw-p 00000000 00:00 0
7fd097301000-7fd097302000 r--p 0001e000 08:05 524412                     /usr/lib64/ld-2.18.so
7fd097302000-7fd097303000 rw-p 0001f000 08:05 524412                     /usr/lib64/ld-2.18.so
7fd097303000-7fd097304000 rw-p 00000000 00:00 0
7fff2606d000-7fff26090000 rw-p 00000000 00:00 0                          [stack]
7fff2613a000-7fff2613c000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00                   [vsyscall]
panic: Aborted -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
octave exited with signal 6


That long printout doesn't happen with e.g., sleep(10) - Octave exits more gracefully then.

For unsaved editor files there's a nice popup about saving the file.

Philip Nienhuis <philipnienhuis>
Group Member
Wed 22 Apr 2015 11:05:48 PM UTC, comment #15: 

I was working on a related bug (#44751) which I wanted to make sure was working first...

OK, in the new attached patch I've added the "check for modified" confirmation when forcing the quit.  I've also interrupted the interpreter before quitting the interpreter to see if that makes a difference for you.

After this I think I will open this to the discussion list to see if others can think of a cleaner way of shutting down the interpreter thread, but it would be good to know how this works for you.

(file #33743)

Dan Sebald <sebald>
Sat 21 Mar 2015 04:44:02 PM UTC, comment #14: 

OK got some results.

You patch didn't apply cleanly; one reject hd to be accomodated in a block, so that may be a reason for the half-baked results I get below.

On both Linux and Windows, it worked the first time:
for ii=1:100;
a = eigs (rand (500));
endfor
could be interrupted by the main menu's File|Exit. Took a second, then I got a popup.

The interrupt may be too "hard" and looks like a system call to kill a non-behaving program, on Windows I also get the "program crashed" popup.

However, subsequent attempts fail (maybe because of me wrongly fitting in the reject).
When I have a file in the editor with -non-saved changes, nothing happens either (but that was the second attempt, maybe it has nothing to do with the editor).

Am I right that that a system call is invoked?
If so think it would be preferrable if Octave's current occupation is interrupted, and then Octave exits gracefully through its own mechanism rather than rely on the system interrupt.

Philip Nienhuis <philipnienhuis>
Group Member
Sat 21 Mar 2015 11:49:23 AM UTC, comment #13: 

Oh no worries, I get sidetracked all the time :)

I will try your new patch this weeekend.

Thanks

Philip Nienhuis <philipnienhuis>
Group Member
Wed 18 Mar 2015 06:26:38 PM UTC, comment #12: 

Sorry, got sidetracked...

Attached is a new version of the patch which simply adds a way to gracefully quit the thread running the interpreter.  Let me know if it works for you.

If you are still seeing a non-zero signal, there is a pre-processor conditional in octave-qt-link.cc:


void
octave_qt_link::quit_interpreter (void)
{
#if 1
  main_thread->quit ();
#else
  delete main_thread;
#endif
}


that you may try changing to see if that helps any.

If this works, we'll at least have a means to force termination gracefully.  Then we'll open the issue to the discussion list to see what makes the most sense to do in terms of forced shutdown sequence.

(file #33391)

Dan Sebald <sebald>
Tue 10 Mar 2015 07:55:27 AM UTC, comment #11: 

Good question.  That error looks like it is coming from the Octave core, right?  I assumed that quitting the application would gracefully stop the Octave CLI thread.  But apparently not.  I'm going to think about this one for a bit, and if you'd like to try something, let me know if it works.  It should be just one or two strategically placed signals or function calls.

The question I have is whether we might have to stop the CLI thread (actually two threads that I see).  The reason is that if we issue the current Qt signal that causes and interrupt, i.e.,


  connect (command_window, SIGNAL (interrupt_signal (void)),
           _octave_qt_link, SLOT (terminal_interrupt (void)));


and


void
terminal_dock_widget::terminal_interrupt (void)
{
  emit interrupt_signal ();
}


it's doesn't solve this issue (I think) because signals across threads are queued, slots across threads aren't processed immediately, unlike in-thread signals/slots.  I think we'd have to simply stop the threads.

As I said, there are two threads, one for the octave CLI and one for the command queue:


      QApplication application (argc, argv);

      octave_cli_thread main_thread (argc, argv);

      application.setQuitOnLastWindowClosed (false);

      main_thread.start ();

      return application.exec ();


and


octave_qt_link::octave_qt_link (QWidget *p)
  : octave_link (), main_thread (new QThread ()),
    command_interpreter (new octave_interpreter ())
{
  connect (this, SIGNAL (execute_interpreter_signal (void)),
           command_interpreter, SLOT (execute (void)));

  connect (command_interpreter, SIGNAL (octave_ready_signal ()),
           p, SLOT (handle_octave_ready ()));

  command_interpreter->moveToThread (main_thread);

  main_thread->start ();


We need some way of accessing and stopping these threads directly, not with slots.  There need to be a couple extra pointers and short functions to do that.

I'll think about for a day or so.

Dan Sebald <sebald>
Tue 10 Mar 2015 06:06:05 AM UTC, comment #10: 

Dan, thank you for the patch. Unfortunately, I get


panic: Segmentation fault -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
octave exited with signal 11


when forcing exit while octave is still busy. Should the current operation be interrupted (and the command queue cleared) before exiting the app?

Torsten Lilge <ttl>
Group Member
Mon 09 Mar 2015 08:11:24 PM UTC, comment #9: 

Give the attached patch a try.  I think it is the best that can be done right now.

Upon running Octave GUI, edit a file so that the GUI asks to save the file upon selecting File|Exit or Cntrl-Q.  Try all various options like


[select File|Exit]



pause(10)
[select File|Exit]
[wait longer than 10 seconds, the force quit dialog should close automatically because core finished]
[select "Cancel" for the save file dialog]



pause(20)
[select File|Exit]
[select "Cancel" button when dialog appears]
[select File|Exit]
[select "Cancel" button when dialog appears]
[select File|Exit]
[select "Cancel" button when dialog appears]
[select "Cancel" for the save file dialog]



pause(20)
[select File|Exit]
[select "Force Exit" button when Force Exit dialog appears]
[all gone]



(file #33305)

Dan Sebald <sebald>
Sun 08 Mar 2015 07:57:23 PM UTC, comment #8: 

"I'm not sure about the delayed timer-based idea, wouldn't it be better to just detect whether Octave is busy at the time the user tries to exit and show the dialog then?"

Yes, sure, but again there are limitations with communications here.  I'm unaware of a way right now to inquire of the Octave core thread "are you computing something or just sitting idle"?  That is what the "exit" in the queue does, in some sense.  If the "exit" gets processed immediately then Octave isn't doing anything.  But we have to allow a short period of time for Octave core to come back and initiate the shutdown otherwise there will be an annoying race condition where the GUI says "Octave is busy" and then also a dialog appears "Save this file", etc.  Make it one second or a half second, if three seconds is too long for someone who launched a three minute processing job.

Do we want to have some type of variable in memory--a mutex of sorts--for which the core Octave processor sets one way when it is busy and sets another way when it is not busy so that the GUI can check that value?  That doesn't feel like a good solution to me.  If the core is busy, it can't tell us it's busy unless every few microseconds it checks to see if it should communicate with the GUI, but that's a waste of CPU cycles really--another not-so-elegant solution.

A good design is needed for an environment with two threads and asynchronous events.  That's post-4.0.

Dan Sebald <sebald>
Sun 08 Mar 2015 05:53:16 PM UTC, comment #7: 

Agree with both of you, a confirmation popup would be a good idea, similar to when there are unsaved files open in the editor.

I'm not sure about the delayed timer-based idea, wouldn't it be better to just detect whether Octave is busy at the time the user tries to exit and show the dialog then?

Mike Miller <mtmiller>
Group Member
Sun 08 Mar 2015 05:51:30 PM UTC, comment #6: 

Just keep in mind a couple things:

1) Both the GUI|File exit and the command line exit have to do a shutdown sequence for the GUI.  That is, both routes have to check if there are files to be saved AND cancel shutdown if the user selects "cancel" during that file-save check.  Now, if you feel that the user shouldn't be allowed to cancel after having selected "exit", then the behavior of the file-save dialog needs to be change under the condition of exiting versus say just closing the tab in the editor.

2) There was no design of a good comm protocol between GUI and worker, so that has restricted what can be done in the GUI.  It's a case of working with limitations at the moment.

Dan Sebald <sebald>
Sun 08 Mar 2015 05:34:41 PM UTC, comment #5: 

Another thing is that AFAIU the main menu's File | Exit instruction sequence is similar or equal to what the OS sends to Octave when e.g., shutting down.
Indeed, when I enter:

for ii=1:1000
eigs (randn (400))
endfor

...and try to shutdown the system I get a popup that program "Octave" is unresponsive.

In far-fetched cases (say, laptop battery nearly exhausted) having Octave obstruct system actions is a bad idea; although I expect any OS to be able to simply ~"kill -9" Octave.
So while I agree with Dan about consistent paths I think the main menu's File|Exit should have absolute priority over anything that happens in the terminal.
It works that way when Octave is running in a rxvt or cmd32.exe terminal as well.

A confirmation popup is a good idea.

Philip Nienhuis <philipnienhuis>
Group Member
Sun 08 Mar 2015 05:24:43 PM UTC, comment #4: 

Hah, https://savannah.gnu.org/bugs/index.php?44485#comment2 beat me by a few minutes.

Yes, the issue in https://savannah.gnu.org/bugs/?41896 is pretty much the same.

One other thing that would need to be done is clearing out the command queue because I suppose the user could have typed in a series of commands.  Say the user types:


>> x = long_running_function();
>> plot(x);
[User chooses File|Exit and an "exit" is placed in the queue]
[Three seconds goes by and dialog asks to exit, says yes]
[The GUI forces an interrupt, then plot() is processed before the "exit" is processed, of course the GUI could simply just stop the worker thread all together first]


Dan Sebald <sebald>
Sun 08 Mar 2015 05:08:22 PM UTC, comment #3: 

Note that there was a change recently in order to make the exit via command line, i.e., typing "exit" in the command window, and exit via GUI, i.e., selecting File | Exit follow a consistent path when doing the shutdown sequence (i.e., check if files need to be saved, etc).  Otherwise, the coordination of such a thing is very convoluted because the GUI needs some type of state variable to decipher where the exit came from, how to stop the Octave core thread from stopping if user wants to cancel, and so on.  The consistent exit-via-command is much easier to deal with.

That said, making the user issue a Cntrl-C to exit the running command is much better than forcing the worker process to close and thereby possibly losing minutes or hours of run time.  However, the best way to do this, and it isn't difficult, just need time, would be if the GUI File | Exit event happens in addition to placing "exit" in the queue is to create a Qt timer and connect a slot to its expiration that will put up a dialog box and ask if the worker Octave thread should be interrupted thereby confirming exit in the process as well.  Set the timer for, say, three second.  The shutdown will then go forward because of the queued exit command.  So there is a little logistics to deal with, but it is all within the GUI's realm so-to-speak rather than having to balance what is going on in two threads.

I can look at this later if no one else has bandwidth, but it might be a couple days.

Dan Sebald <sebald>
Sun 08 Mar 2015 04:52:41 PM UTC, comment #2: 

Maybe File>Exit (or equivalently the exit button of the main window) should raise a warning dialog if Octave is currently busy. Something like "Do you really want to interrupt the interpreter?". If "yes" is pressed then throw an interrupt and exit.
Hopefully we could also handle the case where less is currently running (see bug #41896).

Pantxo Diribarne <pantxo>
Group Member
Sun 08 Mar 2015 02:49:25 PM UTC, comment #1: 

Confirmed here. The "exit" issued by the GUI is queued and works once the long-running command finishes.

Entering Ctrl-C in the command window also interrupts the long-running command and the exit then takes effect immediately.

Mike Miller <mtmiller>
Group Member
Sun 08 Mar 2015 02:19:10 PM UTC, original submission:  

(as suggested by Rik in bug #44445)

Selecting File | Exit from the main menu won't work immediately when Octave is busy.
I'd expect it to be able to interrupt anything Octave is busy with at the user's request (i.e., in the terminal) and then close Octave gracefully.

Just try it with:

for ii=1:100
eigs (randn (400))
endfor

Philip Nienhuis <philipnienhuis>
Group Member

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #34396:  octave-exit_timer-djs2015jul08.patch added by sebald (30KiB - application/octet-stream)
file #34337:  octave-exit_timer-djs2015jun28.patch added by sebald (30KiB - application/octet-stream)
file #34183:  octave-exit_timer-djs2015jun08.patch added by sebald (30KiB - application/octet-stream)
file #33994:  octave-exit_timer-djs2015may12.patch added by sebald (7KiB - application/octet-stream)
file #33743:  octave-exit_timer-djs2015apr22.patch added by sebald (7KiB - application/octet-stream)
file #33391:  octave-exit_timer-djs2015mar18.patch added by sebald (7KiB - application/octet-stream)
file #33305:  octave-exit_timer-djs2015mar09.patch added by sebald (6KiB - application/octet-stream)

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by siko1056 (Posted a comment)
  • -email is unavailable- added by hardy (Posted a comment)
  • -email is unavailable- added by ttl (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by philipnienhuis (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 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-05-28 mtmiller Carbon-CopyRemoved 80942 -
    2020-05-28 siko1056 Dependencies- bugs #58454 is dependent
    2015-07-08 sebald Attached File- Added octave-exit_timer-djs2015jul08.patch, #34396
    2015-06-29 sebald Attached File- Added octave-exit_timer-djs2015jun28.patch, #34337
    2015-06-09 sebald Attached File- Added octave-exit_timer-djs2015jun08.patch, #34183
    2015-05-13 sebald Attached File- Added octave-exit_timer-djs2015may12.patch, #33994
    2015-04-22 sebald Attached File- Added octave-exit_timer-djs2015apr22.patch, #33743
    2015-03-18 sebald Attached File- Added octave-exit_timer-djs2015mar18.patch, #33391
    2015-03-09 sebald Attached File- Added octave-exit_timer-djs2015mar09.patch, #33305
    2015-03-08 mtmiller StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code