4

How can I stop program execution in MATLAB without exiting MATLAB. I'm looking for something like exit(1) in C++.

I've tried exit/quit, but they also kill MATLAB which isn't the behaviour I want.

Ideally I would have used try-catch to bubble up errors, but I'm fixing up existing code and cannot do that due to a deeply nested call stack. Thanks!

EDIT:

I've also tried error and return, but they end up in the invoking functions catch block which isn't what I want either. I simply want to stop the launched program to exit.

Also, Ctrl-C requires the user to stop execution and that's not what I want either.

chappjc
  • 30,359
  • 6
  • 75
  • 132
Nick
  • 4,002
  • 4
  • 30
  • 41
  • This is a really good question, but I don't think there is a solution if you don't want to use exceptions. – s.bandara Feb 21 '14 at 04:24
  • Haha, I was looking for more like 'This is a very simple question'. That's weird. I might have to rely on exit, but the user won't know what hit them unless I output to a log file, but that's just not an option yet. Thanks! – Nick Feb 21 '14 at 04:26
  • I don't exactly understand the question. What do you mean by <>. Can you give an example, say, using an imaginary command? – Autonomous Feb 21 '14 at 04:28
  • 1
    When I run an application which runs into a fatal error that cannot be handled gracefully...I want to stop running that program so that I don't corrupt the computed data and allow the user to make necessary corrections and restart the run so that we can continue where it left off (in essence kill/halt/stop/terminate/exit it). – Nick Feb 21 '14 at 04:32
  • If you know the line on which error(s) may occur, then I think you can do: 1. Save all the workspace 2. When the error comes, keep a record of which statement/function you were running, which I think can be done (as of now, I don't know exactly how to) 3. Run that function when you load the data from the saved .mat file.The problem becomes harder (maybe impossible) when you don't know when to expect the error. Anyway,I think it would be difficult in any programming language, let alone MATLAB (right?). Since it seems to me that, you want to detect the error before it occurs which is impossible. – Autonomous Feb 21 '14 at 04:46
  • My question is not about how to resume the run. I was simply explaining because you wanted clarity. I want to simply exit the program. Your solution doesn't make sense given my question. I can guess you haven't looked beyond Matlab / Octave? – Nick Feb 21 '14 at 04:54
  • I am sorry that I couldn't help you. – Autonomous Feb 21 '14 at 04:57
  • I got the impression because of your statement: <> – Autonomous Feb 21 '14 at 04:59
  • @NickKarnik Please post an answer if you find one. It would be interesting to see how to do this in MATALB. – Autonomous Feb 21 '14 at 05:37
  • Not entirely sure whether I understand what you're looking for, but I have the feeling `keyboard` might be it. It is basically the same as a breakpoint, but not set in the debugger but initiated programmatically. The user gets control through the command window, he can try to fix things, save data, etc., then let the program continue (use `return` in the command window) or abort it by `dbquit`. I'd guess that `dbquit` aborts a program without invoking catch blocks. – edit: Just noticed that vish mentions this, too. – A. Donda Feb 21 '14 at 20:19

3 Answers3

3

What you want is the equivalent of CTRL-C, but to be executed via a command instead of an actual user key press. Using a Java Robot to simulate this key press was suggested by @yuk. This method was nicely utilized by @Pursuit in his function called terminateExecution. Another Java-based solution, interrupt was proposed by @MattB.

To use terminateExecution robustly, I find it is necessary to call a short pause immediately after to give Java time to send the key press and for MATLAB to handle it. All nested try-catch statements will be broken, as I think you need.

killTest.m

function killTest

try
    annoyingFunction();
    fprintf('Does not run.');
catch ME
    fprintf('Fooled again! (%s)\n',ME.message);
end

end

function annoyingFunction()

somethingWrong = true; % more useful code here
if somethingWrong,
    % error('annoyingFunction:catchableError','catchable error');
    terminateExecution % by Pursuit
    % interrupt % by Matt B.
    pause(0.1)
end

end

Example

You return to the command prompt directly from the subfunction, but it looks like the program was terminated by a key press:

>> killTest
Operation terminated by user during killTest>annoyingFunction (line 17)

In killTest (line 4)
    annoyingFunction();
>>

If you instead use error (uncomment the error line inside annoyingFunction to test), it get's caught by the catch statement in killTest:

>> killTest
Fooled again! (catchable error)

Suggested changes to interrupt (simplifications, more reliable acquisition of command window handle, and readability):

function interrupt

import java.awt.event.KeyEvent
import java.lang.reflection.*

base = com.mathworks.mde.cmdwin.CmdWin.getInstance();
hCmd = base.getComponent(0).getViewport().getView();
cmdwin = handle(hCmd,'CallbackProperties');

argSig = javaArray('java.lang.Class',1);
argSig(1) = java.lang.Class.forName('java.awt.event.KeyEvent');

msTime = (8.64e7 * (now - datenum('1970', 'yyyy')));
args = javaArray('java.lang.Object',1);
args(1) = KeyEvent(cmdwin,KeyEvent.KEY_PRESSED,msTime,...
    KeyEvent.CTRL_DOWN_MASK,KeyEvent.VK_C,KeyEvent.CHAR_UNDEFINED);

method = cmdwin.getClass().getDeclaredMethod('processKeyEvent',argSig);
method.setAccessible(true);
method.invoke(cmdwin,args);

Note: If you are OK with typing something to completely quit, just use keyboard and when it stops at the debug prompt (K>>) type dbquit and you will be back to the base workspace command prompt. A cute way to provide a clickable trigger to execute dbquit was provide on the MATLAB Central newsreader. My version of that solution:

fprintf('Terminate execution?\n<a href="matlab: dbquit;">Yes</a> / <a href="matlab: dbcont;">No</a>\n');
keyboard

When this bit of code is run, you get a little prompt like this:

Terminate execution?
Yes / No

The "Yes" and "No" text will be clickable and will either execute dbquit or dbcont.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • what is the difference between this and error('...') apart from the gracefulness? – Autonomous Feb 21 '14 at 17:53
  • @Parag It does not get caught by `catch` statements. (See Nick's comment to Vish.) In the example code, the `fprintf` statements don't run, it just stops execution and returns to the command prompt. Try uncommenting the `error` statement to see what I mean. – chappjc Feb 21 '14 at 18:11
  • @Parag This is why your answer would have worked if not for the part where the user has to hit the keys. :) – chappjc Feb 21 '14 at 18:22
  • @Parag Try putting that in code. Doesn't work unless you are stopped in the debugger. A `keyboard` would get you there, but then you'd need to enter `dbquit` manually. I originally intended to suggest just this, but the OP clearly wants a pure code solution to force the program to kill itself. – chappjc Feb 24 '14 at 23:18
  • Thank you for solving my doubts. – Autonomous Feb 25 '14 at 02:11
  • Sure. BTW, I still think your deleted CTRL-C answer is very useful. Too bad it's gone... – chappjc Feb 25 '14 at 02:15
  • I can undelete that answer. I felt that the OP did not know about such a common thing, but when I realized the full question, I deleted it. – Autonomous Feb 25 '14 at 04:08
  • @Parag I doubt you will get down votes, but I see what you mean. – chappjc Feb 25 '14 at 04:12
  • I'm giving you a +1 on this answer, but it's not the one I've used because it involves quite a bit of coding (unavoidable in this case I agree). Not sure if this should be the answer. If the community thinks so, I can mark it as the answer. My solution was to simply fix the code to throw an exception and fix the call stack to handle it gracefully. – Nick Feb 25 '14 at 23:31
  • @NickKarnik You should mark as an answer what worked for you. Honestly, I'd suggest you post your solution as an answer and accept it. You threw a specific `MException` and caught it with a modified `catch ME` (or series of `catch`es all the way through the call stack) that recognized your specific exception? That's certainly cleaner than a virtual CTRL-C, I'll admit. – chappjc Feb 25 '14 at 23:44
1

You are looking for Ctrl+c key combination. This will abort any program's execution. Take the cursor to the MATLAB's command window and then press Ctrl+c.

Though there are two scenarios when even Ctrl+c cannot stop the execution:

  1. Sometimes, if a MEX-file is getting executed. Ctrl+c won't have any effect.
  2. If your RAM is so full that it cannot even execute Ctrl+c.

Then you have no other option but to go to Task Manager and stop the MATLAB process.

Autonomous
  • 8,935
  • 1
  • 38
  • 77
  • That only works when the user wants to break it. I want to code to stop execution. – Nick Feb 21 '14 at 04:23
  • 1
    This approach could be applied by waiting for keyboard input and asking the user to hit ctrl-C to exit the program (otherwise we could kill Matlab by calling exit)...however, it's still not ideal as it requires user intervention. – Nick Feb 25 '14 at 23:35
  • @NickKarnik True, instead of an error, you could print a message and then `pause` to wait for the CTRL-C. – chappjc Feb 25 '14 at 23:47
0

Do you mean

return 

?

You can also use

error("free text argument")

also (as a debugging tool)

keyboard

(but i think that is deprecated)

vish
  • 1,046
  • 9
  • 26
  • Was just about to post that I've also tried return and error but they both end up in the invoking functions catch blocks which isn't what I want either. – Nick Feb 21 '14 at 04:21