【问题标题】:Catching fortran runtime errors and signals in C++ binding在 C++ 绑定中捕获 fortran 运行时错误和信号
【发布时间】:2019-10-24 09:00:51
【问题描述】:

我希望能够在 C++ 绑定中捕获终止的 Fortran 运行时错误。 我有一个旧的 F90 代码可以绑定并期望出现各种错误,例如数值、IO等

我设法根据以下条件处理 STOP: Intercepting Fortran STOP from C++ 并且能够在 C++ 代码中针对这种情况抛出/捕获异常。

我对“Fortran 中的信号处理”有所了解 https://www.sharcnet.ca/help/images/4/42/Fortran_Signal_Handling.pdf

但是我无法做到这一点,f90 fortran 的示例会很有帮助。

例如,尝试在 fortran 子例程中打开一个不存在的文件会产生运行时错误,并且 C++ 代码终止:

打开(unit=13,FILE="fnameBAD",status="old",action="read",position="rewind")

Fortran 运行时错误:无法打开文件“fnameBAD”:没有这样的文件或目录

我希望能够使用信号捕捉这个和其他运行时错误。

【问题讨论】:

  • 你说signals是什么意思?
  • 信号处理(SIGTERM 或 SIGINT)
  • 你为什么不直接使用try..catch..
  • 当 fortran 代码提交终止信号时,C++ 包装器会立即终止(在 catch 未捕获它之前)。我需要以某种方式抛出异常..似乎以某种方式“调用信号(SIGTERM,myfunction)”可以工作,myfunction 可以抛出异常,但我没有处理这个。
  • Fortran 有办法禁用这些错误消息,使用 iostat= 说明符并检查其返回值。 Fortran 标准中没有任何内容需要编译器发出信号。它需要终止程序。

标签: c++ fortran language-binding


【解决方案1】:

这行不通,至少对于 GFortran。当OPEN 语句失败时,GFortran 运行时库将自行关闭,最后才生成信号。因此,当您可以在信号处理程序中捕获信号时,libgfortran 已经自行关闭(包括关闭所有打开的文件)。

正如 Vladimir F 在评论中所说,解决方案是使用 iostat= 说明符捕获 OPEN 语句中的错误。

【讨论】:

    【解决方案2】:

    我已经实现了类似的东西,用于对来自 C/C++ 的 Fortran 代码的 C 绑定进行单元测试,以使用 setjmplongjmp 捕获 abort 调用(基本上与 an answer in the already linked question 相同):

    #include <setjmp.h>
    #include <signal.h>
    
    jmp_buf jmp_env;
    
    void on_sigabrt(int signum)
    {
        (void) signum; // silence "unused parameter" warning
        longjmp(jmp_env, 1);
    }
    
    void func()
    {
        if (setjmp(jmp_env) == 0) {
            signal(SIGABRT, &on_sigabrt);
            /* YOUR CALLS HERE */
        } else {
            /* ERROR HANDLING GOES HERE */
        }
    }
    

    @janneb 已经描述的问题仍然存在:即使 longjmp 应该将堆栈恢复到 setjmp 的位置,它也不能保证 Fortran 运行时库中的所有内部状态都已恢复。

    事实上,两本书 Modern Fortran: Style and Usage(规则 182)和 The Fortran 2003 Handbook (15.6.4) 都提到不应包装 Fortran 代码在setjmplongjmp 之间。

    另一方面,有些编译器供应商明确提供setjmp/longjmp 包装器(例如Oracle),以及几个具有类似重点的项目:

    话虽如此,正如其他人已经评论的那样,尽可能使用iostat 属性来使用正确的错误处理可能是一种更好(并且更便携)的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      相关资源
      最近更新 更多