在Linux上调用JNI代码时发生奇怪的崩溃;我正确编译我的共享库吗?

时间:2012-12-11 14:00:30

标签: java c linux gcc java-native-interface

看起来只有在使用Java 1.7时才会出现这种情况,无论是使用Oracle还是OpenJDK JRE。使用Java 1.6(Oracle和OpenJDK)时,一切正常。

不久前,我尝试在Linux下编译JNI共享库(用于Java电影播放器​​的LibVLC包装器)。但是,在调用某些本机函数时,JVM在零星和任意时刻崩溃,错误日志引用libc.so中的函数_IO_file_underflow作为有问题的框架。

最终我发现在编译时我只是遗漏了一些GCC标志,问题可能是由某些优化或JVM没想到的。在关注this guidethis question的答案之后,我在编译命令中添加了一些标记,例如-fno-strict-aliasing-pthread,并且一切都运行良好。

至少,这在OpenSuSe 12.1下使用OpenJDK 1.6。不幸的是,在升级到OpenSuse 12.2和OpenJDK 1.7之后,应用程序再次崩溃,并出现以下熟悉的错误消息:

#
[thread -1984603328 also had an error]# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb770ff38, pid=19354, tid=2309835584
#
# JRE version: 7.0_09-b30
# Java VM: OpenJDK Client VM (23.2-b09 mixed mode linux-x86 )
# Problematic frame:
# C  [libc.so.6+0x127f38]  _IO_file_underflow+0x68
#
# 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:
# /usr/fids/build_vlcplayer/hs_err_pid19354.log

#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   http://icedtea.classpath.org/bugzilla
#

我正在使用以下命令进行编译(许多标志可能是多余的):

gcc -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0/include/ -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0/include/linux/ -fno-strict-aliasing -fno-omit-frame-pointer -fPIC -pthread -static-libgcc -D_REENTRANT -Di586 -DARCH='"I586"' -DLINUX -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -D_LITTLE_ENDIAN  -Wall -Wno-unused-parameter -DDEBUG_MODE -shared -lvlc -lc -lX11 movieplayer.c -Wl,-soname,movieplayer.so -o movieplayer.so

我已经尝试使用GCC 3.3版和4.7版。

由于相同的代码在Windows(使用Oracle JDK 1.6或1.7)或OpenSuSe 12.1(使用OpenJDK 1.6)下工作正常,我认为movieplayer.c的实际源代码并不相关;尽管如此,这里发生了崩溃的部分:

/** The LibVLC instance.*/
static libvlc_instance_t * vlcInstance = NULL;

/** The media object representing the video. */
static libvlc_media_t * media = NULL;

/** The media player. */
static libvlc_media_player_t * mediaPlayer = NULL;

...

const char * fname = str + 1;

DEBUGMSG("Opening file: '%s'\n", fname);

// Create a VLC media object for this file.
media = libvlc_media_new_path (vlcInstance, fname);

if(media)
{
    // Parse the media. This allows fetching duration and track info.
    DEBUGMSG("Parsing media.");
    libvlc_media_parse(media);  // <-- Crash occurs at this point.

    // Create the media player.
    DEBUGMSG("Creating a media player.");
    mediaPlayer = libvlc_media_player_new_from_media(media);

    ...
}

...

当我修改此代码时,在调用其他LibVLC函数时,或者在调用POSIX sleep函数时,会在不同时刻发生同样的崩溃。

基本上我的问题是:我是否认为这些崩溃是由于我没有正确编译应用程序而引起的?如果是这样,我做错了什么?

1 个答案:

答案 0 :(得分:1)

以下是对同一问题的讨论: https://github.com/caprica/vlcj/issues/62有解决方法:在VLC中禁用LUA。不知怎的,Ubuntu包装打破了它。有对更多页面的参考也在讨论它。 另请参阅https://bugs.launchpad.net/ubuntu/+source/lua5.1/+bug/1136432