JNA : A fatal error has been detected by the Java Runtime Environment

來源:互聯網
上載者:User
使用JNA 調DLL 常見錯誤之一
錯誤資訊如下
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x72ff2989, pid=1276, tid=4516
# -- 底下這行註明所使用的 JRE, JVM 版本
# JRE version: 6.0_37-b06
# Java VM: Java HotSpot(TM) Client VM (20.12-b01 mixed mode windows-x86 )
-- 錯誤的位置 (來自於C)
# Problematic frame:
# C  [MSVCP80.dll+0x2989]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/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 (0x021ea400):  JavaThread "main" [_thread_in_native, id=4516, stack(0x00390000,0x003e0000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000034

Registers:
EAX=0x00000008, EBX=0x730c775d, ECX=0x0000001c, EDX=0xed646bff
ESP=0x003deec8, EBP=0x003deedc, ESI=0x0000001c, EDI=0x004eaba8
EIP=0x72ff2989, EFLAGS=0x00010212
(…… 省略 N 行)
Register to memory mapping:

EAX=0x00000008 is an unknown value
EBX=0x730c775d is an unknown value
ECX=0x0000001c is an unknown value
EDX=0xed646bff is an unknown value
ESP=0x003deec8 is pointing into the stack for thread: 0x021ea400
EBP=0x003deedc is pointing into the stack for thread: 0x021ea400
ESI=0x0000001c is an unknown value
EDI=0x004eaba8 is an unknown value

(…… 再省略 N 行)
Stack: [0x00390000,0x003e0000],  sp=0x003deec8,  free space=315k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [MSVCP80.dll+0x2989]  std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Inside+0x1

這資訊大概是說 由於C 那邊的 MSVCP80.dll 某個位置引用了非法地址之類的(C 不熟,蠻猜)
聯合調試了下,是由於字串位元的原因:
C 介面定義了 char *HKInstNo  之類的參數,對應到 JAVA 裡,應該是 byte[] 類型,並且末尾要加上 0x00 。
舉個例子:      C 介面函數 : int GetInfo(char *id, carh *cl);
     JNA 介面定義: public int GetInfo(byte[] id, byte[] class);
     JAVA 調用:                       int res = GetInfo("001".getBytes(), "101".getBytes());               此時JVM 就會退出,並會出現上面的錯誤資訊。
          必需給字串加個終止符
          ========= 隔下 ================
          寫了個加終止符的方法
          public byte[] String2byte(String str){                byte[] src = str.getBytes();                byte[] dest = new byte[src.length + 1];                                System.arraycopy(src, 0, dest, 0, src.length);                dest[src.length] = 0x00;     // 這句可以沒有,因為 new 的時候已經初始化為 0                return dest;           }
          然後把上面的JAVA調用改為
          int res = GetInfo(String2byte("001"), String2byte("101"));
     運行通過,能得到傳回值。
=================== 一個類似的錯誤 ============================
結構體定義了byte[] 的長度,並且已經初始化
        public  static  class ORDERINFO  extends Structure {               public   byte  []  orderCreator  =  new   byte  [32];        // 訂單建立 人               public   byte  []  outOrderNo  =  new   byte  [128];   // 外部訂單號 56               public   byte  []  orderType  =  new   byte  [5];               ……………………                            public  GOODSINFO.ByReference  goods  ;                            public   static  class  ByReference  extends  ORDERINFO  implements  Structure.ByReference{}                            public   static  class  ByValue  extends  ORDERINFO  implements  Structure.ByValue{}       }
          ORDERINFO.ByReference orderinfo = new ORDERINFO.ByReference();
          orderinfo.orderCreator = Info.String2byte("zhouyy");
          orderinfo.outOrderNo = Info.String2byte("0510030511355563");
          orderinfo.orderType = Info.String2byte("222S");
          ………………
          orderinfo.goods = goodsinfo;
          
業務中對公用欄位進行賦值,公用欄位所指向的空間已經改變, 因此 orderCreator 的長度已經不是 32位, 而是 zhouyy 6位
所以這邊應該使用 資料拷貝 來複製資料, java 有內部方法用來拷貝數組:  System. arraycopy(src, 0, dest, 0, src.  length ); 
ORDREINFO 結構體裡有個指標 GoodsInfo , 在對 GoodsInfo 複製完資料之後要把 goodsinfo 固定 住記憶體,否則會因為記憶體溢出而導致 dll 蹦潰,反應到JAV 就是JVM 異常退出,並拋出類似上面的 錯誤資訊。
goodsinfo.writer();


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.