开发者

"malloc(): memory corruption"

I'm having a problem w/ malloc in my jni code. The code is intended to let me access the exiv2 library in java. I've tried ruining the code using both the the sun and openjdk 1.6.0 vms and the 1.7.0 (beta) vm.

The error is:

    *** glibc detected *** /usr/lib/jvm/java-6-sun/bin/java: malloc(): memory corruption: 0x00000000418a48f0 ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7f84b8aef4b6]开发者_开发知识库
/lib/libc.so.6(+0x7b55f)[0x7f84b8af355f]
/lib/libc.so.6(__libc_malloc+0x6e)[0x7f84b8af438e]
/usr/lib/libstdc++.so.6(_Znwm+0x1d)[0x7f8469fc3ded]
/home/hjed/libExiv2LJB-C__.so(_ZN9__gnu_cxx13new_allocatorIPN5Exiv25ImageEE8allocateEmPKv+0x49)[0x7f846a601c83]
/home/hjed/libExiv2LJB-C__.so(_ZNSt12_Vector_baseIPN5Exiv25ImageESaIS2_EE11_M_allocateEm+0x2f)[0x7f846a601ab5]
/home/hjed/libExiv2LJB-C__.so(_ZNSt6vectorIPN5Exiv25ImageESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_+0x115)[0x7f846a60169f]
/home/hjed/libExiv2LJB-C__.so(_ZNSt6vectorIPN5Exiv25ImageESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_+0xcf)[0x7f846a601349]
/home/hjed/libExiv2LJB-C__.so(_Z13addExiv2ImagePN5Exiv25ImageE+0x2b)[0x7f846a601115]
/home/hjed/libExiv2LJB-C__.so(Java_Exiv2_ImageFactory_ImageFactory_1Open+0x193)[0x7f846a60214b]
[0x7f84b3dbcc88]
======= Memory map: ========
...
Java Result: 134

The code that appears to be causing the error is (Nb. this code isn't in the stack trace, but prior to adding this code the error did not occur):

Exiv2::FileIo::AutoPtr io (new Exiv2::FileIo(env->GetStringUTFChars(str,false)));
Exiv2::JpegImage * img  =  ( new Exiv2::JpegImage::JpegImage(io, false));

prior to adding this code I was assigning the value of img using:

image *  img= Exiv2::ImageFactory::open(env->GetStringUTFChars(str,false)).get();

and wasn't having any malloc problems (however Exiv2::ImageFactory::open() returns an autoPtr, I can't use an autoPtr for what I want to do).

The error occurs in this code:

jint addExiv2Image(image * i) {
    vec.push_back(i);
    return vec.size();
}

When run with gdb the error occurs in a different location:

gdb backtrace:

#0  0x00007ffff724eba5 in raise (sig=<value optimised out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff72526b0 in abort () at abort.c:92
#2  0x00007ffff728843b in __libc_message (do_abort=<value optimised out>, fmt=<value optimised out>) at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3  0x00007ffff72924b6 in malloc_printerr (action=3, str=0x7ffff7362eab "malloc(): memory corruption", ptr=<value optimised out>) at malloc.c:6283
#4  0x00007ffff729655f in _int_malloc (av=0x7fffa4000020, bytes=24) at malloc.c:4396
#5  0x00007ffff729738e in __libc_malloc (bytes=24) at malloc.c:3660
#6  0x00007ffff6cadbe7 in os::malloc(unsigned long) () from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#7  0x00007ffff68f6bb1 in CHeapObj::operator new(unsigned long) () from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#8  0x00007ffff6cef347 in PlaceholderTable::find_and_add(int, unsigned int, symbolHandle, Handle, PlaceholderTable::classloadAction, symbolHandle, Thread*) ()
   from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#9  0x00007ffff6d89a6c in SystemDictionary::resolve_instance_class_or_null(symbolHandle, Handle, Handle, Thread*) ()
   from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#10 0x00007ffff6d8a243 in SystemDictionary::resolve_or_fail(symbolHandle, Handle, Handle, bool, Thread*) () from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#11 0x00007ffff6b4d537 in find_class_from_class_loader(JNIEnv_*, symbolHandle, unsigned char, Handle, Handle, unsigned char, Thread*) ()
   from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#12 0x00007ffff6b1fc39 in jni_FindClass () from /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so
#13 0x00007fffa36f32cb in JNIEnv_::FindClass (this=0x6131c8, name=0x7fffa36f3628 "Exiv2/Exiv2Image") at /usr/lib/jvm/default-java/include/jni.h:794
#14 0x00007fffa36f3161 in Java_Exiv2_ImageFactory_ImageFactory_1Open (env=0x6131c8, cls=0x7ffff7fd6938, str=0x7ffff7fd6948) at src/ImageFactory.cpp:20
#15 0x00007ffff21d9cc8 in ?? ()
#16 0x0000000000613000 in ?? ()
#17 0x00007ffff7fd68e8 in ?? ()
#18 0x00007fffaa104998 in ?? ()
#19 0x00007ffff7fd6948 in ?? ()
#20 0x00007fffaa104d30 in ?? ()
#21 0x0000000000000000 in ?? ()

and the vm crash report backtrace when running w/ gdb:

/lib/libc.so.6(+0x774b6)[0x7ffff72924b6]
/lib/libc.so.6(+0x7b55f)[0x7ffff729655f]
/lib/libc.so.6(__libc_malloc+0x6e)[0x7ffff729738e]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x5cfbe7)[0x7ffff6cadbe7]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x218bb1)[0x7ffff68f6bb1]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x611347)[0x7ffff6cef347]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x6aba6c)[0x7ffff6d89a6c]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x6ac243)[0x7ffff6d8a243]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x46f537)[0x7ffff6b4d537]
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/libjvm.so(+0x441c39)[0x7ffff6b1fc39]
/home/hjed/libExiv2LJB-C__.so(_ZN7JNIEnv_9FindClassEPKc+0x2b)[0x7fffa36f32cb]
/home/hjed/libExiv2LJB-C__.so(Java_Exiv2_ImageFactory_ImageFactory_1Open+0x1a9)[0x7fffa36f3161]
[0x7ffff21d9cc8]

Thanks for any help,

HJED

Edit: changed vec from an array to a vector as suggested in comments.

Nb. I don't use malloc in any of my code.

Update

I've tried using valgrind to debug, but using:

valgrind --show-emwarns=yes --smc-check=all /usr/bin/java -jar Exiv2LJB-test.jar

the program runs but gives no extra info and using

valgrind --show-emwarns=yes --smc-check=all --trace-children=yes /usr/bin/java -jar Exiv2LJB-test.jar

I get a vm error about SSE2 not being supported. I have read the valgrind FAQ about using it with java and I did follow those instructions.


std::auto_ptr is scoped pointer wrapper which destroys the wrapped object after leaving the scope. If you want to retain the returned object in vector and manually manage its lifetime, change this:

image *  img= Exiv2::ImageFactory::open(env->GetStringUTFChars(str,false)).get();

to

image *  img= Exiv2::ImageFactory::open(env->GetStringUTFChars(str,false)).release();

Then don’t forget to release your objects in the vector when you no longer need them.


Additionaly, if you can use C++11, use the std::vector with combination with std::unique_ptr and they will manage memory for you:

std::vector<std::unique_ptr<image>> vec;

jint addExiv2Image(image * i) {
    vec.push_back(std::unique_ptr<image>(i));
    return vec.size();
}


This means the memory is corrupted. It usually have nothing to do with the code you quote -- it happends long before that. Just your code happens to work on the same memory and discovers the corruption. Running in gdb give different trace further prove this point.

You may try valgrind. Read the FAQ, you need some special for java.


In this call:

Exiv2::ImageFactory::open(env->GetStringUTFChars(str,false)).get();

Make sure that the opening operation has succeeded and you are having a pointer to an image object of a valid state.

Also, in your vector insertion operation, make sure that the pointer you are passing as an argument is pointing to an existing object of a valid state (for example, are you sure the object is in scope?).

I suspect that something is going wrong with the memory when you load the image (and not with the insertion itself - you have initialized your vector properly, haven't you?).

An additional tip: Use uppercase-starting names for classes (for instance: Image instead of image), as this will increase readability in your code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜