Déboguer une application Java sans démarrer la JVM avec des arguments de débogage

96

Normalement, pour attacher un débogueur à un jvm en cours d'exécution, vous devez démarrer le jvm avec des arguments tels que les suivants:

> java -Xdebug -Xrunjdwp:transport=dt_socket,address=1000,server=y,suspend=n

Maintenant, si je veux déboguer un processus qui n'a pas été démarré en mode débogage, que puis-je faire?

Cette situation se produit lorsqu'un système de production (c'est-à-dire démarré sans argument de débogage) présente un bogue «aléatoire» (j'utilise le terme vaguement). Je ne peux donc pas redémarrer le jvm avec les arguments appropriés, car personne ne sait comment reproduire à nouveau le bogue. Est-il impossible de se connecter à la JVM dans cette situation?

Juste pour clarifier, il n'est pas possible d'utiliser des outils comme jdb pour se connecter à des machines virtuelles Java déjà en cours d'exécution à moins qu'elles n'aient été démarrées en mode débogage

à partir de la page de manuel JVM

Une autre façon d'utiliser jdb consiste à l'attacher à une machine virtuelle Java déjà en cours d'exécution. Une VM qui doit être déboguée avec jdb doit être démarrée avec les options suivantes:

Hhafez
la source

Réponses:

48

Vous pourrez peut-être utiliser jsadebugd ( JDK ) pour attacher un serveur de débogage au processus (disponible sur Windows avec les outils de débogage pour Windows ). Il est marqué comme expérimental, vous voudrez peut-être l'essayer d'abord sur une machine de test.

Usage:

jsadebugd <pid>
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=localhost

Le nom du connecteur avec arg peut être trouvé en utilisant jdb -listconnectors.

McDowell
la source
1
J'utilise Linux, donc cela semble être la solution la plus prometteuse
hhafez
Des expériences à partager avec ça?
Thorbjørn Ravn Andersen
1
Mon expérience est que cela a bien fonctionné les fois où j'en avais besoin, en attendant, toutes les instances d'usine du logiciel ne sont pas configurées pour se lancer avec les options de débogage jvm par défaut afin que nous puissions utiliser la méthode prise en charge.
hhafez
Sur Java 11 a jsadebugdété remplacé par jhsdb debugd. Alors ça devient jhsdb debugd --pid <pid>. Voir les diapositives d'une conférence présentant jhsdb et les documents pour jhsdb
Delthas
Il semble qu'il a également SADebugServerAttachingConnectorété supprimé jdb, et je pense que le remplacement est censé être jhsdb hsdb/ jhsdb clhsdb. Je ne trouve pas de documentation sur les arguments à donner jhsdb clhsdb.
Delthas
32

Juste pour clarifier, il n'est pas possible d'utiliser des outils comme jdb pour se connecter à des JVM déjà en cours d'exécution>> sauf s'ils ont été démarrés en mode débogage

en russie soviétique la source vous lit

jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9426
plante en pot
la source
1
Eh
7

VisualVM n'est pas un débogueur, mais vous pouvez obtenir des vidages de threads et des vidages de tas qui peuvent être utiles pour diagnostiquer certains problèmes. Les fonctionnalités les plus utiles nécessitent JVM 5 ou 6.

sk.
la source
le lien ne fonctionne pas .... peut-être que vous supprimez le http: // avant le https: // ... J'aurais mais je n'ai pas encore assez de réputation
Newtopian
+1 VisualVM semble vraiment intéressant. BTW: Le lien est maintenant corrigé.
sleske
5

utiliser jstack (utile en cas de blocage) ou le plugin btrace VisualVM pourrait également faire l'affaire

Vijay
la source
-5

Vous pouvez toujours utiliser jdb et déboguer manuellement: P

OscarRyz
la source
2
J'ai toujours pensé que vous ne pouvez pas vous attacher à jvm avec jdb à moins que le jvm n'ait été démarré avec pour permettre les connexions de débogage Est-ce que je me trompe?
hhafez
Autant que je sache, l'option que vous avez mentionnée est "d'activer" le débogage à distance de votre commande "java" (la VM) Mais vous pouvez également utiliser la commande jdb à la place. Donc, au lieu de java MyApp, vous irez comme jdb MyApp (et déboguez de manière interactive, définissez des points d'arrêt, exécutez, arrêtez, surveillez, etc.)
OscarRyz
1
Je ne pense pas que ce soit correct d'après la page de manuel jdb - start quote Une autre façon d'utiliser jdb est de l'attacher à une machine virtuelle Java qui est déjà en cours d'exécution. Une machine virtuelle qui doit être déboguée avec jdb doit être démarrée avec les options suivantes: - end quote
hhafez
Avec le bon connecteur (non pris en charge pour l'instant), jdb peut se connecter à un processus en cours d'exécution.
Thorbjørn Ravn Andersen