java “malloc():内存损坏”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4687704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"malloc(): memory corruption"
提问by HJED
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.
我在 jni 代码中遇到了 malloc 问题。该代码旨在让我访问 java 中的 exiv2 库。我尝试使用 sun 和 openjdk 1.6.0 vms 和 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:
在添加此代码之前,我使用以下方法分配 img 的值:
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).
并且没有任何 malloc 问题(但是 Exiv2::ImageFactory::open() 返回一个 autoPtr,我不能将 autoPtr 用于我想做的事情)。
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 运行时,错误发生在不同的位置:
gdb backtrace:
gdb 回溯:
#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:
以及运行 w/gdb 时的 vm 崩溃报告回溯:
/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
感谢您的帮助,
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.
编辑:按照评论中的建议,将 vec 从数组更改为向量。
铌。我没有在我的任何代码中使用 malloc。
Update
I've tried using valgrind to debug, but using:
更新
我尝试使用 valgrind 进行调试,但使用:
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.
我收到有关不支持 SSE2 的虚拟机错误。我已经阅读了有关在 Java 中使用它的 valgrind 常见问题解答,并且确实遵循了这些说明。
回答by Palec
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:
std::auto_ptr 是作用域指针包装器,它在离开作用域后销毁被包装的对象。如果要将返回的对象保留在向量中并手动管理其生命周期,请更改以下内容:
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:
此外,如果您可以使用 C++11,请将 std::vector 与 std::unique_ptr 结合使用,它们将为您管理内存:
std::vector<std::unique_ptr<image>> vec;
jint addExiv2Image(image * i) {
vec.push_back(std::unique_ptr<image>(i));
return vec.size();
}
回答by J-16 SDiZ
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.
这意味着内存已损坏。它通常与您引用的代码无关——它发生在很久之前。只是您的代码碰巧在同一内存上工作并发现损坏。在 gdb 中运行给出不同的跟踪进一步证明了这一点。
You may try valgrind. Read the FAQ, you need some special for java.
你可以试试valgrind。阅读FAQ,你需要一些特殊的java。
回答by Nick Louloudakis
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 initializedyour 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.
另一个提示:为类使用大写开头的名称(例如:Image
而不是image
),因为这将提高代码的可读性。