2011-01-14 14 views
0

Ich habe ein Problem mit malloc in meinem jni Code. Der Code soll mir den Zugriff auf die exiv2-Bibliothek in Java ermöglichen. Ich habe versucht, den Code mit der Sonne und Openjdk 1.6.0 Vms und der 1.7.0 (Beta) Vm zu ruinieren."malloc(): Speicherbeschädigung"

Der Fehler ist:.

*** 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 

Der Code, der Fehler zu verursachen scheint, ist (Nb dieser Code ist nicht in der Stack-Trace, aber vor dem Hinzufügen dieser Code der Fehler nicht auftreten):

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

vor diesen Code zum Hinzufügen ich den Wert img verwendet wurde Zuweisung:

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

und hatte keine Malloc-Probleme (aber Exiv2 :: ImageFactory :: open() gibt ein AutoPtr zurück, ich kann kein AutoPtr für das verwenden, was ich tun möchte).

Der Fehler tritt in diesem Code:

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

Wenn mit gdb laufen tritt der Fehler in einem anderen Ort:

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 ??() 

und vm Absturzbericht Backtrace wenn w/gdb ausgeführt wird:

/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] 

Vielen Dank für jede Hilfe,
HJED

Edit: geändert vec aus einem Array zu einem Vektor wie in den Kommentaren vorgeschlagen.
Nb. Ich verwende kein malloc in meinem Code.

aktualisieren
Ich habe mit valgrind zu debuggen versucht, aber mit:

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

das Programm läuft, gibt aber keine zusätzlichen Informationen und mit

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

ich einen vm Fehler erhalten über SSE2 wird nicht unterstützt. Ich habe die Valgrind-FAQ über die Verwendung von Java gelesen und diese Anweisungen befolgt.

+0

weiß nicht, ob dies hilfreich Es scheint jedoch, dass Sie zwanzig Zeiger zuweisen (dh nur 80 oder 160 Byte Speicher, abhängig von der Zeigergröße Ihres Rechners). Wollten Sie das machen? Wenn Sie eigentlich ein Array von 20 Bildobjekten zuweisen wollten, müssen Sie das Sternchen in makeArray() loswerden. –

+0

OP, scheint in diesem Fall würden Sie besser mit einem std :: vector , die die Handhabung einfacher machen würde. –

+0

Ja, ich beabsichtige das zu tun. Exiv2 :: Image (das ich zum Eingeben typisiert habe) ist eine abstrakte Klasse, daher kann ich kein Array mit 20 Bildobjekten deklarieren. – HJED

Antwort

0

Dies bedeutet, dass der Speicher beschädigt ist. Es hat normalerweise nichts mit dem Code zu tun, den du zitierst - es passierte lange davor. Nur Ihr Code passiert zufällig auf dem gleichen Speicher und entdeckt die Korruption. Running in gdb geben verschiedene Spuren weiter beweisen diesen Punkt.

Sie können versuchen valgrind. Lesen Sie die FAQ, Sie brauchen etwas spezielles für Java.

+0

Ich versuchte Valgrind, mit: "valgrind --show-emwarns = yes - smc-check = alle/usr/bin/java -jar Exiv2LJB-test.jar" das Programm läuft, aber gibt keine extra Info. mit "valgrind --show-emwarns = yes --smc-check = alle --trace-kinder = ja/usr/bin/java -jar Exiv2LJB-test.jar" Ich bekomme einen VM-Fehler über SSE2 nicht unterstützt. Ich denke, der erste Satz von Code in Anführungszeichen (der nicht in der Stack-Trace ist) verursacht das Problem, weil vor der Verwendung dieses Codes hatte ich eine andere Möglichkeit der Initialisierung von 'img', die Speicherbeschädigung nicht verursacht. Allerdings war diese Methode nicht dafür geeignet, wie ich die Variable verwenden wollte. – HJED

0

In diesem Aufruf:

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

Vergewissern Sie sich, dass der Öffnungsvorgang erfolgreich war und Sie einen Zeiger auf ein Bildobjekt eines gültigen Zustand.

Stellen Sie in Ihrer Vektoreinfügeoperation außerdem sicher, dass der Zeiger, den Sie als Argument übergeben, auf ein vorhandenes Objekt eines gültigen Status verweist (z. B. ob das Objekt wirklich im Geltungsbereich ist).

Ich vermute, dass etwas mit dem Speicher läuft falsch, wenn Sie das Bild laden (und nicht mit dem Einführen selbst - Sie haben Ihren Vektor richtig initialisiert, nicht wahr).

Ein zusätzlicher Tipp: Verwenden Sie Großbuchstaben-Startnamen für Klassen (zum Beispiel: Image statt image), da dies die Lesbarkeit in Ihrem Code erhöht.

0

std :: auto_ptr ist ein Pointer-Wrapper, der das umgebrochene Objekt nach Verlassen des Bereichs zerstört. Wenn Sie das zurückgegebene Objekt in Vektor beibehalten möchten und manuell seine Lebensdauer verwalten, dies ändern:

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

zu

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

Dann vergessen Sie nicht, Ihre Objekte in den Vektor zu lösen, wenn Sie nicht mehr brauche sie.


Additionaly, wenn Sie C++ 11 verwenden können, verwenden Sie die std :: vector mit Kombination mit std :: unique_ptr und sie werden für Sie Speicher verwalten:

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

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