-
Notifications
You must be signed in to change notification settings - Fork 744
Debugging UnsatisfiedLinkError and StackOverflowError on Linux
Given:
static {
// Register all formats and codecs
avformat.av_register_all();
}
// ffmpeg code usage
Might cause a StackOverflow or UnsatisfiedLinkError
Caused by: java.lang.StackOverflowError
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:637)
at org.bytedeco.javacpp.Loader.load(Loader.java:492)
at org.bytedeco.javacpp.Loader.load(Loader.java:409)
at org.bytedeco.javacpp.avcodec.<clinit>(avcodec.java:13)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.bytedeco.javacpp.Loader.load(Loader.java:464)
at org.bytedeco.javacpp.Loader.load(Loader.java:409)
at org.bytedeco.javacpp.avformat.<clinit>(avformat.java:14)
Check if the Error is still thrown when using java -jar {file} -Xss512k
to increase the stack size.
First, enable debugging, for example by adding slf4j / log4j dependency and configuring debug level:
Loading class org.bytedeco.javacpp.avutil
Loading class org.bytedeco.javacpp.avutil
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libavutil.so.55
Loading /tmp/javacpp28873975186486211/libavutil.so.55
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libjniavutil.so
Loading /tmp/javacpp28873975186486211/libjniavutil.so
Loading class org.bytedeco.javacpp.swresample
Loading class org.bytedeco.javacpp.avutil
Loading class org.bytedeco.javacpp.swresample
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libswresample.so.2
Loading /tmp/javacpp28873975186486211/libswresample.so.2
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libjniswresample.so
Loading /tmp/javacpp28873975186486211/libjniswresample.so
Loading class org.bytedeco.javacpp.avcodec
Loading class org.bytedeco.javacpp.avutil
Loading class org.bytedeco.javacpp.swresample
Loading class org.bytedeco.javacpp.avcodec
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libavcodec.so.57
Loading /tmp/javacpp28873975186486211/libavcodec.so.57
Extracting jar:file:/opt/myapplication/lib/ffmpeg-3.1.2-1.2-linux-x86_64.jar!/org/bytedeco/javacpp/linux-x86_64/libjniavcodec.so
Loading /tmp/javacpp28873975186486211/libjniavcodec.so
(exception occurs here)
In case of a failing load of .so file, you can use ldd -v libjniavcodec.so
and objdump -p libjniavcodec.so
to investigate the dependencies of the lib.
Example output:
$ ldd -v libjniavcodec.so
linux-vdso.so.1 => (0x00007fff90bfe000)
libavcodec.so.57 => /tmp/javacpp90472456501071/./libavcodec.so.57 (0x00007fc31350e000)
libswresample.so.2 => /tmp/javacpp90472456501071/./libswresample.so.2 (0x00007fc3132f2000)
libavutil.so.55 => /tmp/javacpp90472456501071/./libavutil.so.55 (0x00007fc31307b000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc312d52000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc312a4b000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc312835000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc312470000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc312251000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc31204d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc315475000)
Also see: http://www.oracle.com/technetwork/java/javase/crashes-137240.html#gbyzz
4.1.3 Crash due to Stack Overflow
A stack overflow in Java language code will normally result in the offending thread throwing java.lang.StackOverflowError. On the other hand, C and C++ write past the end of the stack and provoke a stack overflow. This is a fatal error which causes the process to terminate.
In the HotSpot implementation, Java methods share stack frames with C/C++ native code, namely user native code and the virtual machine itself. Java methods generate code that checks that stack space is available a fixed distance towards the end of the stack so that the native code can be called without exceeding the stack space. This distance towards the end of the stack is called “Shadow Pages.” The size of the shadow pages is between 3 and 20 pages, depending on the platform. This distance is tunable, so that applications with native code needing more than the default distance can increase the shadow page size. The option to increase shadow pages is -XX:StackShadowPages= n, where n is greater than the default stack shadow pages for the platform.