[libvirt] [libvirt-java] [PATCH] Use virFree in order to release memory acquired from libvirt

Claudio Bley cbley at av-test.de
Wed Jan 8 15:25:29 UTC 2014

When JNA is linked to a different runtime library than libvirt, using
JNA's Native.free will probably lead to crashes as witnessed on

 # A fatal error has been detected by the Java Runtime Environment:
 #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000077363290, pid=10180, tid=9908
 # JRE version: 7.0_25-b16
 # Java VM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01 mixed mode windows-amd64 compressed oops)
 # Problematic frame:
 # C  [ntdll.dll+0x53290]  RtlFreeHeap+0xd0

The root cause is that the libvirt DLL uses MSVCRT as its runtime
library, whereas the jnidispatch DLL of JNA uses a different one.

At runtime, when calling org.sun.com.jna.Native.free() the OS function
RtlFreeHeap is called with an invalid Pointer that was actually
allocated by MSVCRT's malloc.

Basically, we cannot simply mix and match memory allocation functions
from different runtime libraries, but have to call virFree for
pointers orignating from libvirt itself.

So, this patch re-adds and uses the virFree method which had been
removed in commit 3220de292990bed71828fba2f3700bc846d440f2.

Signed-off-by: Claudio Bley <cbley at av-test.de>
 src/main/java/org/libvirt/Library.java     | 4 ++--
 src/main/java/org/libvirt/jna/Libvirt.java | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java
index 0136095..33d3042 100644
--- a/src/main/java/org/libvirt/Library.java
+++ b/src/main/java/org/libvirt/Library.java
@@ -4,6 +4,7 @@ import org.libvirt.jna.Libvirt;
 import com.sun.jna.Native;
 import com.sun.jna.Pointer;
+import com.sun.jna.ptr.PointerByReference;
  * This class represents an instance of the JNA mapped libvirt
@@ -38,8 +39,7 @@ final class Library {
      * Free memory pointed to by ptr.
     static void free(Pointer ptr) {
-        Native.free(Pointer.nativeValue(ptr));
-        Pointer.nativeValue(ptr, 0L);
+        libvirt.virFree(new PointerByReference(ptr));
diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java
index 813f09b..b026b04 100644
--- a/src/main/java/org/libvirt/jna/Libvirt.java
+++ b/src/main/java/org/libvirt/jna/Libvirt.java
@@ -7,6 +7,7 @@ import com.sun.jna.NativeLong;
 import com.sun.jna.Pointer;
 import com.sun.jna.ptr.IntByReference;
 import com.sun.jna.ptr.LongByReference;
+import com.sun.jna.ptr.PointerByReference;
  * The libvirt interface which is exposed via JNA. The complete API is
@@ -171,6 +172,7 @@ public interface Libvirt extends Library {
     int virGetVersion(LongByReference libVer, String type, LongByReference typeVer);
     int virInitialize();
     int virCopyLastError(virError error);
+    void virFree(PointerByReference ptr);
     virError virGetLastError();
     void virResetLastError();
     void virSetErrorFunc(Pointer userData, VirErrorCallback callback);

More information about the libvir-list mailing list