I am trying to interface with a C library libzbc using jnr-ffi. The first function call zbc_open works and returns a pointer to a open device. Then the next call to zbc_get_device_info causes a JVM crash.
What is the cause? How to solve it? I think the error is somewhere in the interface of zbc or my passing parameters but searching for any documentation for JNR yielded no helpful results in google.The crash happens too if i omit the array part in the structure.
I am using the project of jnr-fuse as a starting point because my goal is to write a FUSE filesystem.
C functions:
void zbc_set_log_level( char *log_level )
int zbc_open (const char *filename, int flags, struct zbc_device **dev)
void zbc_get_device_info( struct zbc_device *dev, struct zbc_device_info * info)
C structure zbc_device_info:
enum zbc_dev_type zbd_type
enum zbc_dev_model zbd_model
char zbd_vendor_id [ZBC_DEVICE_INFO_LENGTH]
uint32_t zbd_flags
uint64_t zbd_sectors
uint32_t zbd_lblock_size
uint64_t zbd_lblocks
uint32_t zbd_pblock_size
uint64_t zbd_pblocks
uint64_t zbd_max_rw_sectors
uint32_t zbd_opt_nr_open_seq_pref
uint32_t zbd_opt_nr_non_seq_write_seq_pref
uint32_t zbd_max_nr_open_seq_req
JNR interface:
public interface zbc{
public void zbc_set_log_level(String level);
public int zbc_open(String filename,int flags, PointerByReference p);
public void zbc_get_device_info(Pointer dev,zbc_device_info info);
}
public static class zbc_device_info extends Struct {
int zbd_type;
int zbd_model;
byte zbd_vendor_id[]=new byte[32];
u_int32_t zbd_flags;
u_int64_t zbd_sectors;
u_int32_t zbd_lblock_size;
u_int64_t zbd_lblocks;
u_int32_t zbd_pblock_size;
u_int64_t zbd_pblocks;
u_int64_t zbd_max_rw_sectors;
u_int32_t zbd_opt_nr_open_seq_pref;
u_int32_t zbd_opt_nr_non_seq_write_seq_pref;
u_int32_t zbd_max_nr_open_seq_pref;
protected zbc_device_info(Runtime runtime) {
super(runtime);
}
}
The main function:
public static void main(String[] args) {
zbc z = LibraryLoader.create(zbc.class).load("zbc");
Runtime runtime=Runtime.getRuntime(z);
z.zbc_set_log_level("debug");
PointerByReference pr = new PointerByReference();
int ret=z.zbc_open("/temp/test.img", IO_RDWR,pr);
zbc_device_info info=new zbc_device_info(runtime);
z.zbc_get_device_info(pr.getValue(),info);
}
JVM crash:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fa794300c70, pid=29106, tid=0x00007fa7bd4a4700
#
# JRE version: OpenJDK Runtime Environment (8.0_131-b11) (build 1.8.0_131-8u131-b11-2ubuntu1.16.04.3-b11)
# Java VM: OpenJDK 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [jffi6917022509387828651.so+0x5c70] jffi_releaseArrays+0x60
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/mmmm/jnr-fuse/hs_err_pid29106.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
The declaration of Struct is incorrect. The fields are not declared. Try to use the following declaration:
In hs logs there is a call stack that made the program crash. Can you provide it?