3

I wrote a dynamically linked function for Octave in c++ called "hello".

#include <octave/oct.h>    
DEFUN_DLD (hello, args, ,"Print 42") {
    try{
        octave_value retval ;
        throw ;
        return retval = 42.0 ; 
    }
    catch(...){
        std::cerr << "An error has occurred!" << std::endl;
    }
}

I throw an exception using "throw" to simulate any possible error that can occur in‪ "hello". I compile "hello" using "system" "mkoctfile" in the Octave terminal.

octave:2> system('mkoctfile /home/b/Desktop/hello.cc')
ans = 0

"system" returns "0" to indicate that no errors were found. I run "hello" as a dynamically linked function in the Octave terminal and this is the terminal message I receive:

octave:3> hello
terminate called without an active exception
panic: Aborted -- stopping myself...
attempting to save variables to 'octave-workspace'...
save to 'octave-workspace' complete
Aborted

Is it possible to catch the error and prevent Octave from terminating every time I perform a test run of "hello"? I would be most grateful for a small sample code that throws an exemption and permits Octave to continue to run without terminating and even better if I can display a message of where or what caused the error. Thanks.

==== Added on Feb. 9, 2014 ===========================================================

Thanks Carandraug for explaining to me the difference between a terminating exception and a non-terminating exception. The code below is an example of a terminating exception I encountered that was not intentional. Using the code provide by Carandraug I added lines 8 and 9 which simulate an unintentional terminating exception in order to simulate me writing code with a fatal error.

#include <octave/oct.h>
DEFUN_DLD (hello, args, ,"Print 42") {
  octave_value retval;
  try {
    Matrix matrix_temp ;    // line 8
    matrix_temp(-1,-1) = 1; // line 9
  }
  catch(...) {
    error ("An error has occurred!");
    return retval;
  }
  return retval = 42;
}

Using Carandraug's suggestions on compiling Dynamically Linked Functions for Octave I encountered the following Octave Termination:

octave:3> mkoctfile /home/gin/Desktop/hello.cc
octave:4> hello
*** glibc detected *** octave: double free or corruption (out): 0x0000000002225740 ***
======= Backtrace: =========
...
octave[0x400561]
======= Memory map: ========
...
pack.so.3gf.0panic: Aborted -- stopping myself...
attempting to save variables to `octave-core'...
save to `octave-core' complete
Aborted (core dumped)

I edited the question header with the word "terminating exception" based on the information provided by Carandraug. Let me know if I have to move the revised question into its own post.

When I encountered this error I made the gross assumption that I would unintentionally create other fatal errors in the code that would cause Octave to terminate. I foresaw this as a possible annoying debugging process, especially if Octave after termination would not provide more information on what caused the error. However, I believe it is possible that either their are only a small handful of possible errors that can be written which are too obvious to make that cause terminating exceptions or this is simply the nature of writing c++ code which does not have the "safety .net frame work" I am used to.

Kara
  • 6,115
  • 16
  • 50
  • 57
linuxfreebird
  • 799
  • 2
  • 8
  • 16

1 Answers1

3

Here's an example within Octave's own code that catch errors throw from other libraries. The problem is an empty throw statement actually means to terminate now or propagate a previous throw (see related SO question). In your example, terminating execution immediately is the correct action.

Here's a simply modification of your example that works (I took the liberty to change the return when everything goes well to the end, and return the "bad" within the catch):

#include <octave/oct.h>
DEFUN_DLD (hello, args, ,"Print 42") {
  octave_value retval;
  try {
    throw 1;
  }
  catch(...) {
    error ("An error has occurred!");
    return retval;
  }
  return retval = 42;
}

Note that to print error messages with Octave, you should probably be using Octave's error. Note, after calling error(), don't bother with whatever value you're returning.

Finally, note that you do not need to use system('mkoctfile path_to_source'). Octave already has the function mkoctfile which can be called from the Octave prompt. The following should suffice

octave-cli-3.8.0:1> mkoctfile hello.cc
octave-cli-3.8.0:1> hello
error: An error has occurred!

EDIT: answer to second question

That error you are seeing is not an error that can be caught. Octave is not throwing an uncatchable error with instructions to terminate as in your first example. It's a segfault that happens because you are trying to access elements that do not exist. You are trying the equivalent of

std::vector<int> v (5);
v[7] = 8;
v[-1] = 2;

If you want to prevent this error, then check the size of the matrix before indexing. You are no longer using the Octave scripting language, you are expected to know what you're up to. This segfault is an error in your code, and you need to account for it, something like:

Matrix m  = ...; // the matrix whose elements you want to access   
octave_idx_type i = ...; // the element index you want to access
if (i < m.numel ())
  // do something with m(i)
else
  error ("Dude! This is out-of-bounds");

All this said, there is an Octave building option that will check if you're trying to access an element out of the bounds but I think that is off by default (probably because such check every time an element is accessed would be a big performance hit).

Community
  • 1
  • 1
carandraug
  • 12,938
  • 1
  • 26
  • 38
  • Hello Carandraug. Your answer was very informative. Using the information you provided, I changed the question header to "How to prevent Octave from terminating when C++ Dynamically Linked Function throws a terminating exception?" I edited the question body with an example of an unintentional terminating exception. I look forward to reading your next response. – linuxfreebird Feb 09 '14 at 13:43
  • @linuxfreebird if you now have a different question, you should open a different question, not edit the previous. You are not dealing with an error, you are dealing with a segfault caused by your code. Also, if the answer was complete and correct, don't forget to mark it as correct or upvote it. – carandraug Feb 09 '14 at 16:00
  • Thanks Carandraug. This makes sense. Whenever Octave causes a Segfault, then it is mostly like an index out of bounds issue. This dramatically reduces the number of possible reasons to only one reason. Your second respond answers my question by stating that their is only one error that can cause an Octave termination which is the segmentation fault. This information is invaluable for debugging in the future. – linuxfreebird Feb 09 '14 at 16:24
  • @linuxfreebird well, not even the Octave library is completely free of of bugs but yeah, if you get a segfault in Octave, chances are it's an out of bounds problem. For me, only once it was happening elsewhere, and it was being linked with a somehow corrupted Fortran library. – carandraug Feb 09 '14 at 17:19