我正在使用jni访问Java项目中的exiv2 API,并且在std::_ List_const_iterator::operator ++中收到了SIGSEGV错误。我不确定如何解决此错误。我尝试使用高-Xmx值,并在jdk1.6.0(服务器和cacao JVM)和1.7.0(服务器JVM)上运行。

gdb追踪:

    #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错误:
# 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);
}

谢谢你的帮助,
杰德

更新:添加了代码以检查exifData是否为空(如Alex所表示),exifdata不为空。

编辑:尝试运行Alex推荐的最小测试用例,它可以很好地运行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!";
    }

}

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

最佳答案

对&exifData进行NULL检查为空(始终为false)。

让我们更改下面的行,看看会发生什么。
Exiv2::ExifData &exifData = image->exifData();
=>
Exiv2::ExifData exifData = image->exifData();

10-06 13:34