簡體   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