看来只有在使用Java 1.7时才会出现这种情况,无论是使用Oracle还是OpenJDK JRE。 当使用Java 1.6(包括Oracle和OpenJDK)时,一切都可以find。
前段时间,我尝试在Linux下编译一个JNI共享库(用于Java电影播放器的LibVLC的封装)。 但是,当调用某些本地函数时,JVM在零星的任意时刻崩溃,错误日志引用来自libc.so的函数_IO_file_underflow作为有问题的帧。
最终我发现在编译的时候,我只是错过了一些GCC标志,而这些问题可能是由某些优化引起的,或者是JVM没有想到的。 按照这个指南和这个问题的答案,我添加了一些标志,如-fno-strict-aliasing
和-pthread
编译命令,一切工作完美。
至less,这个工作在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的实际源代码是相关的; 尽pipe如此,这里是崩溃发生的部分:
/** 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
函数的时候会发生同样的崩溃。
基本上我的问题是:我是否正确认为这些崩溃是由于我没有正确编译应用程序? 如果是这样,我做错了什么?
下面是关于同一个问题的讨论: https : //github.com/caprica/vlcj/issues/62解决方法:禁用VLC中的LUA。 不知何故,Ubuntu的包装破坏了它。 有更多的讨论这个页面的引用。 另见https://bugs.launchpad.net/ubuntu/+source/lua5.1/+bug/1136432 。