getting SIGSEGV in std::_List_const_iterator<Exiv2::Exifdatum>::operator++ whilst using jni
I'm using jni to access the exiv2 API in my Java project and I'm getting a SIGSEGV error in std::_List_const_iterator::operator++. I'm uncertain how to fix this error. I've tried using high -Xmx values as well as running on both jdk1.6.0 (server and cacao JVMs) and 1.7.0 (server JVM).
gdb traceback:
#0 0x00007fffa36f2363 in std::_List_const_iterator<Exiv2::Exifdatum>::operator++ (this=0x7ffff7fd3500) at /usr/include/c++/4.4/bits/stl_list.h:223
#1 0x00007fffa36f2310 in std::__distance<std::_List_const_iterator<Exiv2::Exifdatum> > (__first=..., __last=...) at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:79
#2 0x00007fffa36f224d in std::distance<std::_List_const_iterator<Exiv2::Exifdatum> > (__first=..., __last=...) at /usr/include/c++/4.4/bits/stl_iterator_base_funcs.h:114
#3 0x00007fffa36f1f27 in std::list<Exiv2::Exifdatum, std::allocator<Exiv2::Exifdatum> >::size (this=0x7fffa4030910) at /usr/include/c++/4.4/bits/stl_list.h:805
#4 0x00007fffa36f1d50 in Exiv2::ExifData::count (this=0x7fffa4030910) at /usr/local/include/exiv2/exif.hpp:518
#5 0x00007fffa36f1d30 in Exiv2::ExifData::empty (this=0x7fffa4030910) at /usr/local/include/exiv2/exif.hpp:516
#6 0x00007fffa36f1763 in getVars (path=0x7fffa401d2f0 "/home/hjed/PC100001.JPG", env=0x6131c8, obj=0x7ffff7fd37a8) at src/main.cpp:146
#7 0x00007fffa36f19d8 in Java_photo_exiv2_Exiv2MetaDataStore_impl_1loadFromExiv (env=0x6131c8, obj=0x7ffff7fd37a8, path=0x7ffff7fd37a0, obj2=0x7ffff7fd3798)
at src/main.cpp:160
#8 0x00007ffff21d9cc8 in ?? ()
#9 0x00000000fffffffe in ?? ()
#10 0x00007ffff7fd3740 in ?? ()
#11 0x0000000000613000 in ?? ()
#12 0x00007ffff7fd3738 in ?? ()
#13 0x00007fffaa1076e0 in ?? ()
#14 0x00007ffff7fd37a8 in ?? ()
#15 0x00007fffaa108d10 in ?? ()
#16 0x0000000000000000 in ?? ()
Java error:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fac11223363, pid=11905, tid=140378349111040
#
# JRE version: 6.0_20-b20
# Java VM: OpenJDK 64-Bit Server VM (19.0-b09 mixed mode linux-amd64 )
# Derivative: IcedTea6 1.9.2
# Distribution: Ubuntu 10.10, package 6b20-1.9.2-0ubuntu2
# Problematic frame:
# C [libExiff2-binding.so+0x4363] _ZNSt20_List_const_iteratorIN5Exiv29ExifdatumEEppEv+0xf
#
# If you would like to submit a bug report, please include
# instructions how to reproduce the bug and visit:
# https://bugs.launchpad.net/ubuntu/+source/openjdk-6/
# 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 (0x0000000000dbf000): JavaThread "main" [_thread_in_native, id=11909, stack(0x00007fac61920000,0x00007fac61a21000)]
siginfo:si_signo=SIGSEGV: si_errno=0, si_code=128 (), si_addr=0x0000000000000000
Registers:
...
Register to memory mapping:
RAX=0x6c8948f0245c8948
0x6c8948f0245c8948 is pointing to unknown location
RBX=0x00007fac0c042c00
0x00007fac0c042c00 is pointing to unknown location
RCX=0x0000000000000000
0x0000000000000000 is pointing to unknown location
RDX=0x6c8948f0245c8948
0x6c8948f0245c8948 is pointing to unknown location
RSP=0x00007fac61a1f4e0
0x00007fac61a1f4e0 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
RBP=0x00007fac61a1f4e0
0x00007fac61a1f4e0 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
RSI=0x00007fac61a1f4f0
0x00007fac61a1f4f0 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
RDI=0x00007fac61a1f500
0x00007fac61a1f500 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
R8 =0x00007fac0c054630
0x00007fac0c054630 is pointing to unknown location
R9 =0x00007fac61a1f358
0x00007fac61a1f358 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
R10=0x00007fac61a1f270
0x00007fac61a1f270 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
R11=0x00007fac11223354
0x00007fac11223354: _ZNSt20_List_const_iteratorIN5Exiv29ExifdatumEEppEv+0 in /home/hjed/libExiff2-binding.so at 0x00007fac1121f000
R12=0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
R13=0x00007fac13ad1be8
{method}
- klass: {other class}
R14=0x00007fac61a1f7a8
0x00007fac61a1f7a8 is pointing into the stack for thread: 0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
R15=0x0000000000dbf000
"main" prio=10 tid=0x0000000000dbf000 nid=0x2e85 runnable [0x00007fac61a1f000]
java.lang.Thread.State: RUNNABLE
Top of Stack: (sp=0x00007fac61a1f4e0)
...
Instructions: (pc=0x00007fac11223363)
...
Stack: [0x00007fac61920000,0x00007fac61a21000], sp=0x00007fac61a1f4e0, free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libExiff2-binding.so+0x4363] _ZNSt20_List_const_iteratorIN5Exiv29ExifdatumEEppEv+0xf
C [libExiff2-binding.so+0x4310] _ZSt10__distanceISt20_List_const_iteratorIN5Exiv29ExifdatumEEENSt15iterator_traitsIT_E15difference_typeES5_S5_St18input_iterator_tag+0x26
C [libExiff2-binding.so+0x424d] _ZSt8distanceISt20_List_const_iteratorIN5Exiv29ExifdatumEEENSt15iterator_traitsIT_E15difference_typeES5_S5_+0x36
C [libExiff2-binding.so+0x3f27] _ZNKSt4listIN5Exiv29ExifdatumESaIS1_EE4sizeEv+0x33
C [libExiff2-binding.so+0x3d50] _ZNK5Exiv28ExifData5countEv+0x18
C [libExiff2-binding.so+0x3d30] _ZNK5Exiv28ExifData5emptyEv+0x18
C [libExiff2-binding.so+0x3763] _Z7getVarsPKcP7JNIEnv_P8_jobject+0x3e3
C [libExiff2-binding.so+0x39d8] Java_photo_exiv2_Exiv2MetaDataStore_impl_1loadFromExiv+0x4b
j photo.exiv2.Exiv2MetaDataStore.impl_loadFromExiv(Ljava/lang/String;Lphoto/exiv2/Exiv2MetaDataStore;)V+0
j photo.exiv2.Exiv2MetaDataStore.loadFromExiv2()V+9
j photo.exiv2.Exiv2MetaDataStore.loadData()V+1
j photo.exiv2.Exiv2MetaDataStore.<init>(Lphoto/ImageFile;)V+10
j photo.ImageFile.<init>(Ljava/lang/String;)V+11
j test.Main.main([Ljava/lang/String;)V+67
v ~StubRoutines::call_stub
V [libjvm.so+0x428698]
V [libjvm.so+0x4275c8]
V [libjvm.so+0x432943]
V [libjvm.so+0x447f91]
C [java+0x3495] JavaMain+0xd75
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j photo.exiv2.Exiv2MetaDataStore.impl_loadFromExiv(Ljava/lang/String;Lphoto/exiv2/Exiv2MetaDataStore;)V+0
j photo.exiv2.Exiv2MetaDataStore.loadFromExiv2()V+9
j photo.exiv2.Exiv2MetaDataStore.loadData()V+1
j photo.exiv2.Exiv2MetaDataStore.<init>(Lphoto/ImageFile;)V+10
j photo.ImageFile.<init>(Ljava/lang/String;)V+11
j test.Main.main([Ljava/lang/String;)V+67
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x00007fac0c028000 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=11924, stack(0x00007fac11532000,0x00007fac11633000)]
0x00007fac0c025800 JavaThread "CompilerThread1" daemon [_thread_blocked, id=11923, stack(0x00007fac11633000,0x00007fac11734000)]
0x00007fac0c022000 JavaThread "CompilerThread0" daemon [_thread_blocked, id=11922, stack(0x00007fac11734000,0x00007fac11835000)]
0x00007fac0c01f800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=11921, stack(0x00007fac11835000,0x00007fac11936000)]
0x00007fac0c001000 JavaThread "Finalizer" daemon [_thread_blocked, id=11920, stack(0x00007fac11e2d000,0x00007fac11f2e000)]
0x0000000000e36000 JavaThread "Reference Handler" daemon [_thread_blocked, id=11919, stack(0x00007fac11f2e000,0x00007fac1202f000)]
=>0x0000000000dbf000 JavaThread "main" [_thread_in_native, id=11909, stack(0x00007fac61920000,0x00007fac61a21000)]
Other Threads:
0x0000000000e2f800 VMThread [stack: 0x00007fac1202f000,0x00007fac12130000] [id=11918]
0x00007fac0c02b000 WatcherThread [stack: 0x00007fac11431000,0x00007fac11532000] [id=11925]
...
Heap
PSYoungGen total 18432K, used 632K [0x00007fac47210000, 0x00007fac486a0000, 0x00007fac5bc10000)
eden space 15808K, 4% used [0x00007fac47210000,0x00007fac472ae188,0x00007fac48180000)
from space 2624K, 0% used [0x00007fac48410000,0x00007fac48410000,0x00007fac486a0000)
to space 2624K, 0% used [0x00007fac48180000,0x00007fac48180000,0x00007fac48410000)
PSOldGen total 42240K, used 0K [0x00007fac1de10000, 0x00007fac20750000, 0x00007fac47210000)
object space 42240K, 0% used [0x00007fac1de10000,0x00007fac1de10000,0x00007fac20750000)
PSPermGen total 21248K, used 2831K [0x00007fac13810000, 0x00007fac14cd0000, 0x00007fac1de10000)
object space 21248K, 13% used [0x00007fac13810000,0x00007fac13ad3d80,0x00007fac14cd0000)
Dynamic libraries:
...
VM Arguments:
jvm_args: -Dfile.encoding=UTF-8
java_command: test.Main
Launcher Type: SUN_STANDARD
Environment Variables:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
USERNAME=hjed
LD_LIBRARY_PATH=/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-6-openjdk/jre/lib/amd64:/usr/lib/jvm/java-6-openjdk/jre/../lib/amd64
SHELL=/bin/bash
DISPLAY=:0.0
Signal Handlers:
...
--------------- S Y S T E M ---------------
OS:Ubuntu 10.10 (maverick)
uname:Linux 2.6.35-24-generic #42-Ubuntu SMP Thu Dec 2 02:41:37 UTC 2010 x86_64
libc:glibc 2.12.1 NPTL 2.12.1
rlimit: STACK 8192k, CORE 0k, NPROC infinity, NOFILE 1024, AS infinity
load average:0.27 0.31 0.30
/proc/meminfo:
MemTotal: 4048200 kB
MemFree: 106552 kB
Buffers: 838212 kB
Cached: 1172496 kB
SwapCached: 0 kB
Active: 1801316 kB
Inactive: 1774880 kB
Active(anon): 1224708 kB
Inactive(anon): 355012 kB
Active(file): 576608 kB
Inactive(file): 1419868 kB
Unevictable: 64 kB
Mlocked: 64 kB
SwapTotal: 7065596 kB
SwapFree: 7065596 kB
Dirty: 20 kB
Writeback: 0 kB
AnonPages: 1565608 kB
Mapped: 213424 kB
Shmem: 14216 kB
Slab: 164812 kB
SReclaimable: 102576 kB
SUnreclaim: 62236 kB
KernelStack: 4784 kB
PageTables: 44908 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 9089696 kB
Committed_AS: 3676872 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 332952 kB
VmallocChunk: 34359397884 kB
HardwareCorrupted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 48704 kB
DirectMap2M: 4136960 kB
CPU:total 8 (4 cores per cpu, 2 threads per core) family 6 model 26 stepping 5, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, ht
Memory: 4k page, physical 4048200k(106552k free), swap 7065596k(7065596k free)
vm_info: OpenJDK 64-Bit Server VM (19.0-b09) for linux-amd64 JRE (1.6.0_20-b20), built on Dec 10 2010 19:45:55 by "buildd" with gcc 4.4.5
main.cpp:
jobject toJava(std::auto_ptr<Exiv2::Value> v, const char * type, JNIEnv * en开发者_如何学运维v) {
jclass stringClass;
jmethodID cid;
jobject result;
stringClass = env->FindClass("photo/exiv2/Value");
cid = env->GetMethodID(stringClass, "<init>", "(Ljava/lang/String;Ljava/lang/Object;)V");
jvalue val;
if ((strcmp(type, "String") == 0) || (strcmp(type, "String") == 0)) {
val.l = env->NewStringUTF(v->toString().c_str());
} else if (strcmp(type, "Short") == 0) {
val.s = v->toLong(0);
} else if (strcmp(type, "Long") == 0) {
val.j = v->toLong(0);
}
result = env->NewObject(stringClass, cid, env->NewStringUTF(v->toString().c_str()), val);
return result;
}
void inLoop(std::auto_ptr<MetadataContainer> md, JNIEnv * env, jmethodID mid, jobject obj) {
jvalue values[2];
const char* key = md->key().c_str();
values[0].l = env->NewStringUTF(key);
values[1].l = toJava(md->getValue(), md->typeName(), env);
env->CallVoidMethodA(obj, mid, values);
}
void getVars(const char* path, JNIEnv * env, jobject obj) {
//Load image
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path);
assert(image.get() != 0);
image->readMetadata();
//load method
jclass cls = env->GetObjectClass(obj);
jmethodID mid = env->GetMethodID(cls, "exiv2_reciveElement", "(Ljava/lang/String;Lphoto/exiv2/Value;)V");
//Load IPTC data
Exiv2::IptcData &iptcData = image->iptcData();
//check if java method exists
if (mid != NULL) {
//is there any IPTC data
if (iptcData.empty()) {
std::string error(path);
error += ": failed loading IPTC data, there may not be any data";
} else {
Exiv2::IptcData::iterator end = iptcData.end();
for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) {
std::auto_ptr<MetadataContainer> meta(new MetadataContainer(md));
inLoop(meta, env, mid, obj);
}
}
Exiv2::ExifData &exifData = image->exifData();
//added this to check whether exifData is valid
if (&exifData == NULL) {
std::cout << "Error: exifData is null" << std::endl;
return;
}
//is there any Exif data
if (exifData.empty()) { //error occurs here (main.cpp:146)
std::string error(path);
error += ": failed loading Exif data, there may not be any data";
} else {
Exiv2::ExifData::iterator end = exifData.end();
for (Exiv2::ExifData::iterator md = exifData.begin(); md != end; ++md) {
std::auto_ptr<MetadataContainer> meta(new MetadataContainer(md));
inLoop(meta, env, mid, obj);
}
}
} else {
std::string error(path);
error += ": failed to load method";
}
}
JNIEXPORT void JNICALL Java_photo_exiv2_Exiv2MetaDataStore_impl_1loadFromExiv(JNIEnv * env, jobject obj, jstring path, jobject obj2) {
const char* path2 = env->GetStringUTFChars(path, NULL);
getVars(path2, env, obj);
env->ReleaseStringUTFChars(path, path2);
}
Thanks for any help,
HJEDUPDATE: added code to check whether exifData is null as sugested by Alex, exifdata is not null.
EDIT: Tried running minimal test case as sugested by Alex, it runs fine w/out the jni stuff
int main(int argc, char* const argv[]) {
const char* path = "/home/hjed/PC100001.JPG";
//Load image
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path);
std::cout << "loaded image" << std::endl;
assert(image.get() != 0);
image->readMetadata();
std::cout << "read metadata" << std::endl;
Exiv2::ExifData &exifData = image->exifData();
std::cout << "loaded exif2data" << std::endl;
//is there any Exif data AND check that method exists
if (exifData.empty()) {
std::string error(path);
error += ": failed loading Exif data, there may not be any data";
std::cout << error;
} else {
std::cout << "finished!";
}
}
output:
loaded image
Error: Directory Olympus2 with 1536 entries considered invalid; not read.
read metadata
loaded exif2data
finished!
Program exited normally.
NULL check on &exifData is nothing (always false).
Let's change below line and see what happen.
Exiv2::ExifData &exifData = image->exifData();
=>
Exiv2::ExifData exifData = image->exifData();
Looks like image->exifData()
is returning a bad value. I'm assuming the library code is OK and that Exiv2::ExifData is not something you control (or wrote).
Check the value returned before attempting to call empty
on it.
Don't worry about what's at the top of the callstack -- that's just internal std C++ library implementation details.
Edit: Try to reproduce this without the JVM in a minimal test case. That way you'll know if there's a bug in the Exiv2 library or not.
精彩评论