Free Pascal library module crashes Java VM under Linux only -- works OK under Windows, OS-X
Original Reporter info from Mantis: Paul Milenkovic
-
Reporter name: Paul Milenkovic
Original Reporter info from Mantis: Paul Milenkovic
- Reporter name: Paul Milenkovic
Description:
A Free Pascal library module, compiled to a .so file under Linux, randomly crashes Java after being loaded into the VM with the Java System.loadLibrary() call.
The enabling of FPU interrupts is a known cause of crashing Java when a Delphi or Free Pascal library is called with JNI, but I am masking FPU interrupts and Java still crashes. I am only getting the problem for Linux-i386 -- masking the FPU interrupts corrects all crashing problems under Mac OS-X i386, and FPU interrupts under Windows are not a problem because Java under Windows remasks the FPU interrupts upon return from a native method.
The Java program TestJ invokes the Java System.loadLibrary("TestFPC") method to load libTestFPC.so as a native library module. TestFPC is a "null" library -- there are no native functions in it that get called from TestJ apart from whatever initialization takes place when libTestFPC.so gets loaded.
The crashes are non-deterministic. Sometimes the Java app TestJ crashes on
startup. Other times it takes multiple invocations and dismissals of the File
Chooser with the Files Open command to cause the crash. The crash appears to
happen sooner if you drag the TestJ main window with the mouse across the
Desktop before trying the Files Open command.
This problem occurs for a Java program invoking System.loadLibrary() an a Free
Pascal-generated .so file only -- this is not a problem for a gcc-generated .so
file. I have also tried invoking ppc386 with and without the -Cg flag to specify position independent code (PIC).
What other changes to process state or unmasking of interrupts is the Free
Pascal startup code doing apart from the FPU exceptions? I am already masking
the FPU interrupts because in the absence of doing this, I get floating-point
exceptions from the Java File Chooser, and masking those exceptions eliminates
floating-point exceptions. What other conditions does Free Pascal trap that C++ generally ignores?
Additional information:
Two modules: TestFPC.pas compiles with Free Pascal to libTestFPC.so, TestJ.java compiles with javac to TestJ.class. Compiling the Free Pascal library module into the current directory, running Java with
java -Djava.library.path=. TestJ
can result in the random error reported as
An unhandled exception occurred at $nnnnnnnn
EAccessViolation: Access violation
$nnnnnnnn
The best way to trigger the error is to drag the main window of TestJ across the desktop and then to try several invocations and dismissals of a Java File Chooser with the Files Open command (don't open any file, just open the File Chooser with Files Open and then cancel out, and do this about four or five times to trigger the crash).
TestFPC.pas -- compile with /usr/bin/ppc386 TestFPC.pas -Mdelphi -Sh -Rintel
library TestFPC;
uses math;
function GetFPUCW: Word;
asm
MOV EAX,0
PUSH EAX
FNSTCW [ESP].Word
POP EAX
end;
begin
Writeln('8087 Control word',GetFPUCW:10);
ClearExceptions;
SetExceptionMask([exInvalidOp,
exDenormalized,
exZeroDivide,
exOverflow,
exUnderflow,
exPrecision]);
SetPrecisionMode(pmDouble);
Writeln('8087 Control word',GetFPUCW:10);
end.
TestJ.java contains
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestJ extends JFrame
{
private File some_file = new File(".");
private JFileChooser fc = new JFileChooser(some_file);
public void filesOpen()
{
if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
some_file = fc.getSelectedFile();
}
}
public void filesExit()
{
System.exit(0);
}
public TestJ()
{
super("TestJ");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println("initComponents");
initComponents();
System.out.println("createMenuBar");
setJMenuBar(createMenuBar());
System.out.println("pack");
pack();
System.out.println("setVisible");
setVisible(true);
System.out.println("constructor done");
}
private JMenuBar createMenuBar()
{
JMenuBar menuBar = new JMenuBar();
JMenu menu;
JMenuItem menuItem;
// Create Files menu
menu = new JMenu("Files");
menuBar.add(menu);
// Add Open command to Files menu
menuItem = new JMenuItem("Open");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {filesOpen();}});
menu.add(menuItem);
// Add Exit command to Files menu
menu.addSeparator();
menuItem = new JMenuItem("Exit");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {filesExit();}});
menu.add(menuItem);
return menuBar;
}
private void initComponents()
{
// This main panel fills the main window (JFrame) content pane --
// allows setting the main window preferred size.
JPanel pnlMain = new JPanel();
pnlMain.setPreferredSize(new Dimension(800, 600));
getContentPane().add(pnlMain, BorderLayout.CENTER);
System.loadLibrary("TestFPC");
}
public static void main(String[] args)
{
EventQueue.invokeLater(
new Runnable() {
public void run() {new TestJ();}
}
);
}
}
Mantis conversion info:
- Mantis ID: 12704
- Version: 2.2.2
- Fixed in version: 2.4.0
- Fixed in revision: 13077 (#f6d452c2)
- Monitored by: » luizamerico (Luiz Americo)