繁体   English   中英

为什么在 JVM 下运行时,我的 Ada 共享库会出现“存储错误”

[英]Why am I getting “storage error” on my Ada shared library when running under a JVM

我们有一个由 GnatPro 19.2 编译的 Ada 共享库,我们通过 JNA 调用来调用它。

我们的应用程序在 windows 下运行良好。 在 Linux 下移植时,应用程序随机崩溃并出现 Ada 异常:

storage error or erroneous memory access.

使用 gdb(附加进程)进行调试并没有多大帮助。 我们得到了各种 SIGSEGV,我们继续,过了一会儿我们得到了存储错误,没有可用的调用堆栈。

我们的共享库可以与 python 本机调用一起使用,没有任何问题。 问题可能出在 Java 方面。

尝试切换 JVM(openjdk 或官方 jdk)没有运气。

为什么是这样? 有没有办法解决它?

第一个提示是在尝试将调试器附加到应用程序时获得一堆 SIGSEGV,然后在继续时看到程序恢复。

这意味着 SIGSEGV 信号是在 Java 端处理的,正如Why do java app crash in gdb? .

Java 使用推测性负载。 如果指针指向可寻址的 memory,则加载成功。 很少有指针不指向可寻址的 memory,并且尝试的加载会生成 SIGSEGV ... java 运行时拦截,使 memory 再次可寻址,并重新启动加载指令。

现在会发生什么,默认情况下,GNAT 运行时安装一个的信号处理程序来捕获 SIGSEGV 并重定向到一个干净的 Ada 异常。 Ada 异常的一个有趣特性是它们可以打印堆栈跟踪,即使没有调试器。 这个 SIGSEGV 处理程序重定向允许这样做。

但是在 Java 的情况下,由于 Java 使用推测性负载,因此在 java 方面不时会出现 SIGSEGV。 因此,当 Ada 共享库被加载和初始化时,Ada SIGSEGV 处理程序被安装,并捕获那些“正常”的 SIGSEGV,并立即中止。

请注意,它不会在 Windows 下发生。 由于 Windows 在处理 memory 违规访问时的限制,java 运行时可能无法使用此推测加载机制。

信号处理在s-intman.adb中完成

 --  Check that treatment of exception propagation here is consistent with
  --  treatment of the abort signal in System.Task_Primitives.Operations.

  case signo is
     when SIGFPE  => raise Constraint_Error;
     when SIGILL  => raise Program_Error;
  --   when SIGSEGV => raise Storage_Error;  -- commenting this line should fix it
     when SIGBUS  => raise Storage_Error;
     when others  => null;
  end case;
end Notify_Exception;

现在我们必须重建一个新的本机运行时并使用它而不是默认运行时。 这是相当乏味且容易出错的。 该文件是 gnarl 库的一部分。 我们必须使用正确的选项动态重建 gnarl 库-gnatp -nostdinc -O2 -fPIC以创建 gnatrl 库替换......并在升级编译器时再次这样做......

幸运的是,AdaCore 提供了另一种解决方案:

首先在.gpr项目目录中创建一个编译指示文件(我们称之为no_sigsegv.adc ),其中包含:

pragma Interrupt_State (SIGSEGV, SYSTEM); 

指示运行时不要安装 SIGSEGV 处理程序

然后将此添加到.gpr文件的Compiler package 中:

  package Compiler is
    ...
      for local_configuration_pragmas use Project'Project_dir & "/no_sigsegv.adc";

并从头开始重建一切。 测试:没有任何一次崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM