2014年1月14日 星期二

[記錄] Use virFree in order to release memory acquired from libvirt

圖片來源:digitalnewsasia


這幾天都在嘗試解一個Bug...Libvirt-java Binding Library (透過JNA)在 windows 64bit 的環境執行會一直crach,但是32 bit 環境卻不會?!不過老實說當看到以下jvm crash dump 訊息,還真的一點頭緒都沒有...

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000770532d0, pid=2984, tid=7160
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [ntdll.dll+0x532d0]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x0000000001e9d800):  JavaThread "main" [_thread_in_native, id=7160, stack(0x0000000001f20000,0x0000000002020000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000001eeaa38
.
.
[略]
.
.
Stack: [0x0000000001f20000,0x0000000002020000],  sp=0x000000000201f1b0,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [ntdll.dll+0x532d0]

[error occurred during error reporting (printing native stack), id 0xc0000005]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.sun.jna.Native.free(J)V+0
j  org.libvirt.Library.free(Lcom/sun/jna/Pointer;)V+4
j  org.libvirt.Domain.getOSType()Ljava/lang/String;+23
j  test.main([Ljava/lang/String;)V+279
v  ~StubRoutines::call_stub

.
.
[略]
.
.
---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x00000000095c8000 JavaThread "Thread-0" [_thread_blocked, id=4192, stack(0x0000000009ea0000,0x0000000009fa0000)]
  0x0000000007e02800 JavaThread "Service Thread" daemon [_thread_blocked, id=4056, stack(0x00000000091d0000,0x00000000092d0000)]
  0x0000000007dfb800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=4460, stack(0x0000000008a90000,0x0000000008b90000)]
  0x0000000007ded800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2424, stack(0x0000000009060000,0x0000000009160000)]
  0x0000000007dec000 JavaThread "Attach Listener" daemon [_thread_blocked, id=5272, stack(0x0000000008800000,0x0000000008900000)]
  0x0000000007dea800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=4508, stack(0x0000000008f10000,0x0000000009010000)]
  0x0000000001ddf800 JavaThread "Finalizer" daemon [_thread_blocked, id=2548, stack(0x0000000008da0000,0x0000000008ea0000)]
  0x0000000001dd9800 JavaThread "Reference Handler" daemon [_thread_blocked, id=3800, stack(0x0000000008bb0000,0x0000000008cb0000)]
=>0x0000000001e9d800 JavaThread "main" [_thread_in_native, id=7160, stack(0x0000000001f20000,0x0000000002020000)]
.
.
.
.

一大堆系統資訊根本看不出所以然,唯一比較看的懂得只有標記紅色的部份,看起來似乎是JNA 在Call Free Memory的時候出問題。

於是乎開始瞎子摸象,可能是JDK 版本問題? JNA版本問題?Libvirt 問題? Windows DLL for 32bit or  64 bit?

還好我又弱又懶不死心的Google相關的關鍵字,找到了這篇[libvirt-java] [PATCH] Use virFree in order to release memory acquired from libvirt,已經有強者遇到者個問題也解決了!!結果答案是...
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.

ps. MSVCRT .DLL is the Microsoft C runtime library

God....這讓我非常好奇要具備怎樣的本職學能才可以由這些dump 中看出這些問題?並且找出這是使用兩種不同的DLL造成的(Libvirt DLL 與 JNA 的 jnidispatch DLL ),更不用說還能提供Patch...

特此記錄一下...Orz...

張貼留言