2011-01-02 1 views
2

J'utilise jni pour accéder à l'API exiv2 dans mon projet Java et j'obtiens une erreur SIGSEGV dans std :: _ List_const_iterator: : opérateur ++. Je ne suis pas sûr de savoir comment corriger cette erreur. J'ai essayé d'utiliser des valeurs élevées de Xmx, ainsi que de courir sur jdk1.6.0 (JVM serveur et cacao) et 1.7.0 (JVM serveur).obtenir SIGSEGV dans std :: _ List_const_iterator <Exiv2 :: Exifdatum> :: operator ++ en utilisant jni

gdb retraçage:

#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 Erreur:

# 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 * env) { 
    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); 
} 

Merci pour toute aide,
HJED

MISE À JOUR: Ajout d'un code pour vérifier si exifData est null comme corrigé par Alex, exifdata n'est pas nul.

EDIT: Essayé en cours d'exécution cas de test minimal comme sugested par Alex, il fonctionne très bien avec/les trucs JNI

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!"; 
    } 

} 

sortie:

loaded image 
Error: Directory Olympus2 with 1536 entries considered invalid; not read. 
read metadata 
loaded exif2data 
finished! 
Program exited normally. 

Répondre

0

On dirait image->exifData() est de retour une mauvaise valeur. Je suppose que le code de la bibliothèque est OK et que Exiv2 :: ExifData n'est pas quelque chose que vous contrôlez (ou écrivez).

Vérifiez la valeur retournée avant d'essayer d'appeler empty dessus. Ne vous inquiétez pas de ce qui se trouve en haut de la pile des appels: il s'agit uniquement des détails d'implémentation de la bibliothèque C++ std interne. Editer: Essayez de reproduire ceci sans la JVM dans un cas de test minimal. De cette façon, vous saurez s'il existe un bogue dans la bibliothèque Exiv2 ou non.

+0

j'ai ajouté du code pour vérifier si exifData est nul et ce n'est pas. En dehors de vérifier si c'est nul, il n'y a aucun moyen pour moi de vérifier si c'est une mauvaise valeur. – HJED

+0

Essayé avec seulement le code C++. Je reçois toujours une erreur SIGSEV, mais il se produit quelques lignes après où il utilise JNI. (voir ci-dessus) – HJED

+0

@HJED, postez un cas de test * minimal * de votre code C++ uniquement en cas d'échec. –

0

NULL vérifier sur & exifData est rien (toujours faux).

Passons en-dessous de la ligne et voyons ce qu'il se passe.

Exiv2::ExifData &exifData = image->exifData();

=>

Exiv2::ExifData exifData = image->exifData();

+0

Cela fait que l'erreur JNI soit lancée sur cette ligne au lieu de l'emplacement d'origine. Le backtrace se termine par: Exiv2 :: ExifKey :: clone() const() from /usr/lib/libexiv2.so.6 – HJED

Questions connexes