-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
What is the bug?
Using the Java bindings to GDAL 3.11.3, the JVM will crash when the Dataset finalizer runs and trys to close the Dataset object. Stack traces often look like the following:
Current thread (0x0000018bc00ef160): JavaThread "Finalizer" daemon [_thread_in_native, id=22988, stack(0x0000006f4eb00000,0x0000006f4ec00000) (1024K)]
Stack: [0x0000006f4eb00000,0x0000006f4ec00000], sp=0x0000006f4ebff220, free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [gdal.dll+0x549dc7]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.gdal.gdal.gdalJNI.delete_Dataset(J)V+0
j org.gdal.gdal.Dataset.delete()V+25
j org.gdal.gdal.Dataset.finalize()V+1
j java.lang.System$2.invokeFinalize(Ljava/lang/Object;)V+1 [email protected]
j java.lang.ref.Finalizer.runFinalizer(Ljdk/internal/access/JavaLangAccess;)V+115 [email protected]
j java.lang.ref.Finalizer$FinalizerThread.run()V+29 [email protected]
v ~StubRoutines::call_stub 0x0000018b759f100d
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000070
The problem is intermittent: most often the crash will occur but sometimes it does not. Most often the stack trace is like the above, sometimes it crashes elsewhere in the Java libraries making it look like the heap is being corrupted.
Steps to reproduce the issue
The following sample program frequently triggers this problem:
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import static org.gdal.gdalconst.gdalconstConstants.GDT_Int32;
public class GdalCrashJvm {
public static void main(String[] args) {
gdal.AllRegister();
Driver drv = gdal.GetDriverByName("GTiff");
Dataset ds = drv.Create("c:/tmp/test2.tif", 10, 10, 1, GDT_Int32, new String[]{});
Band bd = ds.GetRasterBand(1);
System.err.println("First closing");
bd.GetDataset().Close();
ds = null;
bd = null;
System.gc();
ds = gdal.Open("c:/tmp/test2.tif");
bd = ds.GetRasterBand(1);
System.err.println("Second closing");
bd.GetDataset().Close();
ds = null;
bd = null;
System.gc();
System.gc();
try {
Thread.sleep(2000);
} catch (Exception ignore) {
}
}
}
Versions and provenance
OS Windows 11 Pro 2H2 Build 22000.556
GDAL 3.11.3 pulled from github and built using conda as per instructions at https://gdal.org/en/stable/development/dev_environment.html
Java version 21
Additional context
As I built the small self contained example I noted that the error would not happen if I closed the Dataset object using the Dataset.Close() method. However, when I closed the dataset using Band.GetDataset().Close() the error will frequently occur.
My workaround for this problem is to close the dataset using Dataset.Close() instead of Band.GetDataset().Close(). I am reporting this to let you know of the issue which may have other implications. Even though Band.GetDataset().Close() is not a preferred way of doing things, it really should not be leading to crashing the JVM.