2009-08-21 19 views
13

Ma machine virtuelle Java a bloqué le fichier et le fichier hs_err a montré qu'il s'est bloqué lors de la tentative de chargement d'une classe. Spécifiquement en essayant de memcpy ([libc.so.6 + 0x6aa2c] memcpy + 0x1c). J'ai regardé le fichier .class et j'ai pu déterminer quelle classe était chargée.Plantage de la machine virtuelle pendant l'opération memcpy pendant le chargement de la classe

Mais quelqu'un peut-il me dire ce qui pourrait causer cela ou comment je pourrais déterminer plus sur la cause? Si la JVM était à court de mémoire, ne lancerait-elle pas une erreur? Tout conseil est grandement apprécié.

J'ai inclus un extrait de mon fichier hs_err.

# 
# An unexpected error has been detected by Java Runtime Environment: 
# 
# SIGBUS (0x7) at pc=0x005aba2c, pid=20841, tid=2427227056 
# 
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b05 mixed mode) 
# Problematic frame: 
# C [libc.so.6+0x6aa2c] memcpy+0x1c 
# 
# If you would like to submit a bug report, please visit: 
# http://java.sun.com/webapps/bugreport/crash.jsp 
# 

--------------- T H R E A D --------------- 

Current thread (0x90d0dc00): JavaThread "ORDERHANDLER" [_thread_in_native, id=20881] 

siginfo:si_signo=7, si_errno=0, si_code=2, si_addr=0x915e3000 

Registers: 
EAX=0x91218298, EBX=0xb7f2e71c, ECX=0x0000079b, EDX=0x915dfef2 
ESP=0x90ac6a34, EBP=0x90ac6a60, ESI=0x915e2ffd, EDI=0x914f0a0d 
EIP=0x005aba2c, CR2=0x915e3000, EFLAGS=0x00010206 

Top of Stack: (sp=0x90ac6a34) 
0x90ac6a34: b7f29d4b 914ed930 915dff20 00004f49 
0x90ac6a44: 082e7bc4 00006f6f 00004243 00004f49 
0x90ac6a54: b7f2e71c 080e3e54 00000000 90ac6a90 
0x90ac6a64: b7f29fbb 080e3b00 080e3e54 00000000 
0x90ac6a74: 00000000 90d0dc00 00000000 d68dd1b6 
0x90ac6a84: b7f2e71c 90ac6ad8 90d0dcec 90ac6f00 
0x90ac6a94: b7f21169 080e3b00 90ac6ad8 0000002b 
0x90ac6aa4: 0000002b 90ac6ad8 00000008 00000000 

Instructions: (pc=0x005aba2c) 
0x005aba1c: 8b 74 24 08 fc d1 e9 73 01 a4 d1 e9 73 02 66 a5 
0x005aba2c: f3 a5 89 c7 89 d6 8b 44 24 04 c3 90 90 90 90 90 

Stack: [0x90a78000,0x90ac9000), sp=0x90ac6a34, free space=314k 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
C [libc.so.6+0x6aa2c] memcpy+0x1c 
C [libzip.so+0xbfbb] ZIP_GetEntry+0x10b 
C [libzip.so+0x3169] Java_java_util_zip_ZipFile_getEntry+0xc9 
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J 
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry; 
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry; 
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource; 
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource; 
J java.net.URLClassLoader$1.run()Ljava/lang/Object; 
v ~StubRoutines::call_stub 
V [libjvm.so+0x20bbbd] 
V [libjvm.so+0x30a6b8] 
V [libjvm.so+0x20ba50] 
V [libjvm.so+0x26190b] 
C [libjava.so+0xaa5c] Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2Ljava_security_AccessControlContext_2+0x3 
c 
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; 
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class; 
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; 
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; 
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3 
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2 
v ~StubRoutines::call_stub 
V [libjvm.so+0x20bbbd] 
V [libjvm.so+0x30a6b8] 
V [libjvm.so+0x20b6e1] 
V [libjvm.so+0x20b7ca] 
V [libjvm.so+0x367621] 
V [libjvm.so+0x3662a5] 
V [libjvm.so+0x365357] 
V [libjvm.so+0x365112] 
V [libjvm.so+0x1adb03] 
V [libjvm.so+0x1aeb32] 
V [libjvm.so+0x2d75cb] 
V [libjvm.so+0x2d8a94] 
V [libjvm.so+0x2d8a17] 
V [libjvm.so+0x1fe7f8] 
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221 
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12 
j com.aqua.api.EEDefaultWorkerThread.run()V+96 
v ~StubRoutines::call_stub 
V [libjvm.so+0x20bbbd] 
V [libjvm.so+0x30a6b8] 
V [libjvm.so+0x20b4d0] 
V [libjvm.so+0x20b55d] 
V [libjvm.so+0x27b795] 
V [libjvm.so+0x383ef0] 
V [libjvm.so+0x30b5a9] 
C [libpthread.so.0+0x5371] 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
J java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J 
J java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry; 
J java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry; 
J sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource; 
J sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource; 
J java.net.URLClassLoader$1.run()Ljava/lang/Object; 
v ~StubRoutines::call_stub 
J java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; 
J java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class; 
J java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; 
J sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; 
j java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3 
j java.lang.ClassLoader.loadClassInternal(Ljava/lang/String;)Ljava/lang/Class;+2 
v ~StubRoutines::call_stub 
j com.aqua.foms.book.OrderHandler.handleNewOrder(Lcom/aqua/NmsApi/OrderMap;Lcom/aqua/api/AtsMessage;)V+221 
j com.aqua.foms.book.FMSNewOrderTask.execute()V+12 
j com.aqua.api.EEDefaultWorkerThread.run()V+96 
v ~StubRoutines::call_stub 

--------------- P R O C E S S --------------- 

Java Threads: (=> current thread) 
    0x080c9c00 JavaThread "pool-1-thread-3" [_thread_blocked, id=18725] 
    0x0824f800 JavaThread "pool-1-thread-2" [_thread_blocked, id=13693] 
    0x91217c00 JavaThread "AquaSchedulerService_7" daemon [_thread_blocked, id=23675] 
    0x91215c00 JavaThread "AquaSchedulerService_6" daemon [_thread_blocked, id=23001] 
0x91215400 JavaThread "AquaSchedulerService_5" daemon [_thread_blocked, id=22759] 
    0x91213400 JavaThread "AquaSchedulerService_4" daemon [_thread_blocked, id=22410] 
    0x91212c00 JavaThread "AquaSchedulerService_3" daemon [_thread_blocked, id=22262] 
    0x08316400 JavaThread "pool-1-thread-1" [_thread_blocked, id=22260] 
    0x0827d000 JavaThread "JmsConn_1_sender_0" daemon [_thread_blocked, id=21196] 
    0x90d0cc00 JavaThread "Timer-0" [_thread_blocked, id=20882] 
=>0x90d0dc00 JavaThread "ORDERHANDLER" [_thread_in_native, id=20881] 
    0x90d0d400 JavaThread "TradeInviteMonitor" [_thread_blocked, id=20880] 
    0x90d09c00 JavaThread "ROUTERT" [_thread_blocked, id=20878] 
    0x90d09000 JavaThread "TIBCO EMS Session Dispatcher (33197)" [_thread_blocked, id=20877] 
    0x08310800 JavaThread "DORDERHANDLER" [_thread_blocked, id=20874] 
    0x90d01c00 JavaThread "Thread-12" daemon [_thread_blocked, id=20873] 
    0x90d03000 JavaThread "Thread-11" daemon [_thread_in_native, id=20872] 
    0x082e1c00 JavaThread "DELAYEDORDMON" [_thread_blocked, id=20871] 
    0x082e8000 JavaThread "DBUPD" [_thread_blocked, id=20870] 
    0x914e5000 JavaThread "pool-2-thread-1" [_thread_blocked, id=20869] 
    0x914e3c00 JavaThread "StatusStatsEventDispatcherThread" [_thread_blocked, id=20868] 
    0x082c8400 JavaThread "TimerQueue" daemon [_thread_blocked, id=20866] 
    0x082ca000 JavaThread "MDATATHREAD" [_thread_blocked, id=20865] 
    0x082c9400 JavaThread "AquaSchedulerService_2" daemon [_thread_blocked, id=20864] 
    0x9122b000 JavaThread "DestroyJavaVM" [_thread_blocked, id=20843] 
    0x91200800 JavaThread "FirmMatchingServer" [_thread_blocked, id=20863] 
    0x914de800 JavaThread "TIBCO EMS TCPLink Reader (32084)" daemon [_thread_in_native, id=20861] 
    0x9122a400 JavaThread "TIBCO EMS Connections Pinger" daemon [_thread_blocked, id=20859] 
    0x914d4000 JavaThread "WDISTQ" [_thread_blocked, id=20858] 
    0x9121f400 JavaThread "JmsConn_1_connector_0" daemon [_thread_blocked, id=20857] 
    0x914d8000 JavaThread "JmsConn_1_receiver_0" daemon [_thread_blocked, id=20856] 
    0x9149ac00 JavaThread "AquaSchedulerService_1" daemon [_thread_blocked, id=20855] 
    0x9149b400 JavaThread "AquaSchedulerService_0" daemon [_thread_blocked, id=20854] 
    0x9142a000 JavaThread "MySQL Statement Cancellation Timer" daemon [_thread_blocked, id=20852] 
    0x91425c00 JavaThread "Dispatcher-Thread-0" daemon [_thread_blocked, id=20851] 
    0x080bf800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=20849] 
    0x080bdc00 JavaThread "CompilerThread0" daemon [_thread_blocked, id=20848] 
    0x080bcc00 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=20847] 
    0x080a9800 JavaThread "Finalizer" daemon [_thread_blocked, id=20846] 
    0x080a8800 JavaThread "Reference Handler" daemon [_thread_blocked, id=20845] 

Other Threads: 
    0x080a5400 VMThread [id=20844] 
    0x080c1000 WatcherThread [id=20850] 

VM state:not at safepoint (normal execution) 

VM Mutex/Monitor currently owned by a thread: None 

Répondre

22

Nous avons observé des erreurs similaires. notre suspect actuel est des fichiers jar qui sont réécrits (par un processus de mise à niveau) pendant que le processus est en cours d'exécution.

+0

c'est tout :) - merci – richs

1

Autre qu'une simple plume. bug dans la JVM (mise à niveau vers la dernière version et espérer que cela ne se reproduira pas) - ou quelques buggy 3. bibliothèques de parties utilisant JNI, il y a 2 autres choses "intéressantes" qui pourraient causer cela.

  1. défaillance matérielle - mauvaise RAM est souvent un bon candidat ot un système de fichiers endommagé pourrait provoquer un entraînement squameuse pourrait être un coupable aussi. Si vous utilisez Solaris, vous pouvez obtenir des erreurs SIGBUS si le fichier class/jar a été tronqué juste au moment où la JVM doit y accéder dans les cas où la machine virtuelle Java convertit le fichier jar/class.

+0

« en quelque sorte le fichier classe/pot a été tronquée » semble logique; quand j'essaye de supprimer un fichier jar je reçois un [ERREUR] Echec de l'exécution de l'objectif org.apache.maven.plugins: maven-clean-plugin: 2.4.1: clean (default-clean) sur le projet MyProject: Echec nettoyer le projet: Impossible de supprimer C: \ Utilisateurs \ tshrestha \ MyProject \ target \ MonProjet-1.0-SNAPSHOT.jar -> [Aide 1] –

14

La réponse 1 est correcte. L'implémentation de java.util.zip. * Est en faute. Si vous remplacez un fichier zip/jar qu'un programme Java a actuellement "ouvert" (a mis en cache l'objet ZipFile/JarFile), il utilisera les données de table des matières (COT) mises en cache lues dans le fichier d'origine , et va essayer et utiliser cela pour décompresser les données dans le fichier remplacé. Le code de l'inflation n'est pas robuste et va carrément planter lorsqu'il est présenté avec de mauvaises données.

Les programmes Unix normaux conservent les fichiers ouverts pendant qu'ils travaillent avec eux. Si vous remplacez le fichier, le programme qui l'utilise a toujours accès à l'original qu'il a ouvert, grâce au descripteur de fichier ouvert.

L'implémentation java.util.zip. * D'OpenJDK a choisi de ne pas conserver les descripteurs de fichiers ouverts pour les fichiers zip/jar. Une raison à cela pourrait être que Java est souvent invoqué avec des centaines de fichiers jar dans le chemin de la classe, et les concepteurs ne voulaient pas utiliser des centaines de descripteurs de fichiers sur les fichiers jar seuls, laissant le programme lui-même. Ainsi, ils ferment les descripteurs de fichiers dès qu'ils ont lu la table des matières jar/zip, et perdent définitivement l'accès au fichier jar/zip d'origine, si son contenu change.

Pour une raison quelconque, ZipFile ne sait pas ou ne peut pas dire qu'un fichier zip/jar a changé. Si c'était le cas, il pourrait relire la table des matières ou lancer une sorte d'erreur si ce n'est pas possible. En outre, même si la table des matières restait valide, le gonfleur se bloque en cas de données erronées. Que se passerait-il si la table des matières ZIP était valide mais que le flux de données dégonflé était délibérément erroné?

Voici un programme de test qui prouve que java.util.zip. * Ne conserve pas les descripteurs de fichiers ouverts pour les fichiers zip/jar et ne détecte pas que le fichier zip a changé.

import java.util.zip.*; 
import java.io.*; 

public class ZipCrashTest { 
    public static void main(String args[]) throws Exception { 
     // create some test data 
     final StringBuilder sb = new StringBuilder(); 
     for (int i = 0; i < 100000; i++) sb.append("Hello, World\n"); 
     final byte[] data = sb.toString().getBytes(); 

     // create a zip file 
     try (ZipOutputStream zo = new ZipOutputStream(new FileOutputStream("test1.zip"))) { 
      zo.putNextEntry(new ZipEntry("world.txt")); zo.write(data, 0, data.length); zo.closeEntry(); 
      zo.putNextEntry(new ZipEntry("hello.txt")); zo.write(data, 0, data.length); zo.closeEntry(); 
     } 

     // create a second valid zip file, but with different contents 
     try (ZipOutputStream zo = new ZipOutputStream(new FileOutputStream("test2.zip"))) { 
      zo.putNextEntry(new ZipEntry("hello.txt")); zo.write(data, 0, data.length); zo.closeEntry(); 
      zo.putNextEntry(new ZipEntry("world.txt")); zo.write(data, 0, data.length); zo.closeEntry(); 
     } 

     // open the zip file 
     final ZipFile zf = new ZipFile("test1.zip"); 

     // read the first file from it 
     try (InputStream is = zf.getInputStream(zf.getEntry("hello.txt"))) { 
      while (is.read() != -1) { /* do nothing with the data */ } 
     } 

     // replace the contents of test1.zip with the different-but-still-valid test2.zip 
     Runtime.getRuntime().exec("cp test2.zip test1.zip"); 

     // read another entry from test1.zip: it does not detect that the file has changed. 
     // the program will crash here 
     try (InputStream is = zf.getInputStream(zf.getEntry("world.txt"))) { 
      while (is.read() != -1) { /* do nothing */ } 
     } 
    } 
} 

L'exécution de ce programme devrait vous donner un plantage JVM:

# A fatal error has been detected by the Java Runtime Environment: 
# 
# SIGBUS (0x7) at pc=0x00007fb0fbbeef72, pid=4140, tid=140398238095104 
... 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
C [libzip.so+0x4f72] Java_java_util_zip_ZipFile_getZipMessage+0x1132 
C [libzip.so+0x5d7f] ZIP_GetEntry+0xcf 
C [libzip.so+0x3904] Java_java_util_zip_ZipFile_getEntry+0xb4 
j java.util.zip.ZipFile.getEntry(J[BZ)J+0 
j java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;+38 
j ZipCrashTest.main([Ljava/lang/String;)V+476 

Le principal bogue déposé contre la machine virtuelle Java pour cela est JDK-4425695 : Updating jar files crashes running programs.

RFE 6929479: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile implémente une propriété système dans JDK7 - sun.zip.disableMemoryMapping - que vous pouvez utiliser comme solution de contournement.

0

Je ne sais pas si vous avez résolu le problème parce que j'ai rencontré exactement le même problème. Je n'utilise mmap pour mapper un fichier de 64 Ko dans une mémoire et utiliser memcpy pour copier des données vers/depuis le tampon. La même erreur est survenue lorsque j'utilise JNI ou lorsque j'utilise JNA. Je suis un programmeur expérimenté JNI depuis des années et je suis exactement implémenté la même logique dans un programme C pur qui fonctionne plutôt bien. Je suppose que c'est un bug du JDK qui piège certains SIG. Mais je n'ai vraiment pas le temps de le creuser plus. Pour l'instant, j'ai décidé d'abandonner cette approche et essayer d'autres façons de faire quelque chose que je veux faire.

Si vous êtes intéressé par la raison pour laquelle je fais cela, je veux juste implémenter un fichier mappé de mémoire de thread sûr dans JNI. Parce que dans l'implémentation de JDK, la position est une variable globale dans ByteBuffer (qui est mappée à partir de FileChannel). Je veux juste utiliser une instance MemoryMappedBuffer pour accéder au contenu de plusieurs threads que j'ai fait dans un programme C++.

BTW, j'utilise JDK 7 dans Mac OS X 10.10.

1

Problème: le fichier zip/JAR est en cours d'écrasement en cours d'utilisation. Le code OpenJDK pour le format de fichier ZIP est en code C natif pour toute recherche d'entrée, la création nécessite plusieurs aller-retour d'invocations jni coûteuses. Le code d'implémentation C native utilise mmap pour mapper dans la table du répertoire central, ce qui représente un risque important de crash de vm lorsque le fichier jar sous-jacent est écrasé par du nouveau contenu alors qu'il est encore utilisé par d'autres ZipFile. L'utilisation de - Dsun.zip.disableMemoryMapping = true résoudra le problème,

JDK9 Les versions d'accès anticipé sont disponibles avec une solution pour cela.

Vérifiez la question originale https://bugs.openjdk.java.net/browse/JDK-8142508 qui a été fixé à 9 construction d'accès rapide 97.