J'exécute Tomcat 5.5 sur x86_64 CentOS 5.7 à l'aide d'Oracle Java 1.6.0 32 bits.
Le processus JVM utilisé par Tomcat a 6421 pid. Tomcat fonctionne bien.
Lorsqu'il est exécuté jstack
, il échoue avec:
[root@mybox ~]# jstack 6421
6421: well-known file is not secure
Pour obtenir une sortie raisonnable, je dois utiliser l'option force:
[root@mybox ~]# jstack -F 6421
Attaching to process ID 6421, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0-b16
Deadlock Detection:
No deadlocks found.
(...)
Les questions sont:
jstack
ne fonctionne-t-elle pas sans une option force?Merci d'avance.
Cela est probablement dû au fichier dans/tmp utilisé pour communiquer avec le processus ayant des autorisations différentes de celle obtenue par jstack. Le fichier en question est/tmp/hsperfdata_ $ USER/$ PID.
Je ne sais pas pourquoi cela fonctionne avec -F car la page de manuel dit simplement "Forcer un vidage de pile lorsque" jstack [-l] pid "ne répond pas."
lorsque -F
est utilisé, le jvm sera figé .
Si vous pouvez trouver le file: /tmp/hsperfdata_$USER/$PID
. Essayez simplement de passer au $USER
, puis au exec jstack
. Vous utilisez " root ", mais ce processus peut ne pas appartenir à root.
si $USER
ne possède pas de shell de connexion (utilisateurs de démon) et ne peut donc pas basculer vers cet utilisateur, vous pouvez contourner ce problème en utilisant Sudo -u $USER jstack $PID
.
J'ai eu ce problème lorsque j'ai essayé d'exécuter jstack
en tant que root
.
Une fois que je suis passé à un autre utilisateur cela a fonctionné immédiatement.
Je voudrais juste ajouter que vous devrez peut-être spécifier votre répertoire/tmp avec l'option -J, car toutes les applications n'utilisent pas celui par défaut.
jstack -J-Djava.io.tmpdir=PATH -l PID
J'obtenais la même erreur en cours d'exécution:
watch -n .5 "jstack 26259"
Faire comme Sudo ça marche:
Sudo watch -n .5 "jstack 26259"
Si vous ne voulez pas vous soucier de l'utilisateur et que vous pouvez travailler en tant que root et que vous pouvez tuer le processus, vous pouvez utiliser ce dernier recours:
kill -s SIGQUIT $PID
Cela enregistrera le vidage de threads dans le journal de votre console, par exemple, dans le cas de Tomcat, cela nécessiterait un grepping pour "Thread complet" qui est le début du dump de thread dans logs/catalina.out, puis le fichier tdump se présente comme suit:
DUMP_IDX=`grep -n 'Full thread' logs/catalina.out | tail -1 | cut -d':' -f1`
sed -n $DUMP_IDX,1000000000000000000p logs/catalina.out > jstack-kill-thread-dump-0309.tdump
Le moyen le plus simple est probablement de:
voir le propriétaire du processus par ps -ef | grep "nom du processus"
puis basculez vers cet utilisateur et exécutez la commande.
jcmd PID GC.run ou tout autre utilitaire Java
Une chose que j'ai remarqué que personne n'a discuté ici est; vous devez également définir la variable Java_HOME. vérifiez ceci par echo $ Java_HOME
En plus d'exécuter avec le même utilisateur, assurez-vous que l'ID de groupe de l'utilisateur exécutant jstack/jmap est également identique au processus.
Examinez le code source qui vérifie l’autorisation de fichier (ligne 347). Nous pouvons voir que la fonction qui obtient l'ID de groupe n'est pas un tableau. Il est donc possible que l'utilisateur ait d'autres groupes qui ont démarré le processus.
Vous devrez peut-être modifier le groupe principal de l'utilisateur:
#usermod -g group -G user user
C'est la couche que j'utilise pour m'assurer que j'utilise toujours les autorisations utilisateur appropriées:
proc="my-process-name"; pid=`pgrep -f "${proc}"`; Sudo -u "#`ps axo uid,pid | grep "${pid}" | tr -s " " | cut -f2 -d" "`" /usr/bin/jstack -l "${pid}" > /mnt/dumps/"${proc}"-`date +%s`.txt
Pour utiliser correctement jstack, vous devez l'exécuter avec le même utilisateur que le processus.