【问题标题】:How to prevent Octave from terminating when C++ Dynamically Linked Function throws a terminating exception?当 C++ 动态链接函数抛出终止异常时,如何防止 Octave 终止?
【发布时间】:2014-02-08 15:25:47
【问题描述】:

我在 C++ 中为 Octave 编写了一个动态链接函数,名为“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;
    }
}

我使用“throw”抛出异常来模拟“hello”中可能发生的任何错误。我在 Octave 终端中使用“system”“mkoctfile”编译“hello”。

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

“system”返回“0”表示没有发现错误。我在 Octave 终端中将“hello”作为动态链接函数运行,这是我收到的终端消息:

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

每次我执行“hello”的测试运行时,是否可以捕获错误并防止 Octave 终止?我将非常感谢一个小的示例代码,它抛出一个豁免并允许 Octave 继续运行而不会终止,如果我能显示一条关于哪里或什么导致错误的消息,那就更好了。谢谢。

==== 2014 年 2 月 9 日添加 ==================================== ========================

感谢 Carandraug 向我解释终止异常和非终止异常之间的区别。下面的代码是我遇到的非故意终止异常的示例。使用 Carandraug 提供的代码,我添加了第 8 行和第 9 行,它们模拟了意外终止异常,以模拟我编写的代码出现致命错误。

#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;
}

使用 Carandraug 关于为 Octave 编译动态链接函数的建议,我遇到了以下 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)

我根据 Carandraug 提供的信息编辑了带有“终止异常”一词的问题标题。如果我必须将修改后的问题移到自己的帖子中,请告诉我。

当我遇到这个错误时,我做了一个粗略的假设,即我会无意中在代码中创建其他致命错误,从而导致 Octave 终止。我预见这可能是一个令人讨厌的调试过程,尤其是如果终止后的 Octave 不会提供有关导致错误的原因的更多信息。但是,我相信它们可能只是一小部分可以编写的错误,这些错误太明显而无法导致终止异常,或者这只是编写不具有“安全性”的 c++ 代码的本质。网络框架”我已经习惯了。

【问题讨论】:

    标签: c++ octave


    【解决方案1】:

    这是 Octave 自己的代码中的 example,用于捕获其他库抛出的错误。问题是一个空的 throw 语句实际上意味着现在终止或传播先前的 throw (see related SO question)。在您的示例中,立即终止执行是正确的操作。

    这是对您的示例的简单修改(当一切顺利到最后,我冒昧地更改了回报,并在捕获中返回“坏”):

    #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;
    }
    

    请注意,要使用 Octave 打印错误消息,您可能应该使用 Octave's error。请注意,在调用 error() 之后,不要理会您返回的任何值。

    最后请注意,您不需要使用system('mkoctfile path_to_source')。 Octave 已经有函数mkoctfile 可以从 Octave 提示符调用。以下应该足够了

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

    编辑:回答第二个问题

    您看到的错误不是可以捕获的错误。 Octave 不会像您的第一个示例中那样使用终止指令抛出无法捕获的错误。这是一个段错误,因为您试图访问不存在的元素。您正在尝试相当于

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

    如果你想防止这个错误,那么在索引之前检查矩阵的大小。您不再使用 Octave 脚本语言,您应该知道自己在做什么。此段错误是您的代码中的错误,您需要对其进行说明,例如:

    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");
    

    所有这一切,有一个 Octave 构建选项将检查您是否尝试访问越界的元素,但我认为默认情况下这是关闭的(可能是因为每次访问元素时都会进行此类检查性能大受打击)。

    【讨论】:

    • 你好 Carandraug。你的回答非常翔实。使用您提供的信息,我将问题标题更改为“如何防止 Octave 在 C++ 动态链接函数引发终止异常时终止?”我用一个无意终止异常的例子编辑了问题正文。我期待着阅读您的下一个回复。
    • @linuxfreebird 如果你现在有不同的问题,你应该打开一个不同的问题,而不是编辑以前的问题。您不是在处理错误,而是在处理由代码引起的段错误。此外,如果答案完整且正确,请不要忘记将其标记为正确或投票。
    • 感谢 Carandraug。这是有道理的。每当 Octave 导致 Segfault 时,它就像一个索引越界问题。这极大地减少了可能原因的数量,只有一个原因。您的第二个回答回答了我的问题,指出它们只是一个可能导致 Octave 终止的错误,即分段错误。这些信息对于将来的调试非常宝贵。
    • @linuxfreebird 好吧,即使 Octave 库也不是完全没有错误,但是是的,如果您在 Octave 中遇到段错误,很可能这是一个越界问题。对我来说,只有一次它发生在其他地方,并且它与一个以某种方式损坏的 Fortran 库链接。
    猜你喜欢
    • 1970-01-01
    • 2014-09-18
    • 2011-09-04
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    相关资源
    最近更新 更多