Depure um aplicativo java sem iniciar o JVM com argumentos de depuração

95

Normalmente, para anexar um depurador a um jvm em execução, você precisa iniciar o jvm com argumentos como os seguintes:

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

Agora, se eu quiser depurar um processo que não foi iniciado no modo de depuração, o que posso fazer?

Essa situação surge quando um sistema de produção (ou seja, iniciado sem argumentos de depuração) exibe um bug 'aleatório' (uso o termo vagamente). Portanto, não posso reiniciar o jvm com os argumentos apropriados, porque ninguém sabe como reproduzir o bug novamente. É impossível conectar ao JVM nesta situação?

Só para esclarecer, não é possível usar ferramentas como jdb para anexar a JVMs já em execução, a menos que tenham sido iniciadas no modo de depuração

da página de manual da JVM

Outra maneira de usar o jdb é anexá-lo a uma VM Java que já está em execução. Uma VM que deve ser depurada com jdb deve ser iniciada com as seguintes opções:

Hhafez
fonte

Respostas:

47

Você pode usar jsadebugd ( JDK ) para anexar um servidor de depuração ao processo (disponível no Windows com as Ferramentas de Depuração para Windows ). Está marcado como experimental, então você pode querer testá-lo primeiro em uma máquina de teste.

Uso:

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

O nome do conector com arg pode ser encontrado usando jdb -listconnectors.

McDowell
fonte
1
Estou usando o Linux, então esta parece ser a solução mais promissora
hhafez
Alguma experiência para compartilhar com isso?
Thorbjørn Ravn Andersen
1
Minha experiência é que funcionou bem nas vezes que eu precisava, entretanto, todas as instâncias de fábrica do software não estão configuradas para iniciar com opções de depuração jvm por padrão, para que possamos usar o método suportado.
hhafez
No Java 11 jsadebugdfoi substituído por jhsdb debugd. Então isso se torna jhsdb debugd --pid <pid>. Veja os slides de uma palestra apresentando jhsdb e os documentos para jhsdb
Delthas
Parece que SADebugServerAttachingConnectorfoi removido jdbtambém, e acho que a substituição deveria ser jhsdb hsdb/ jhsdb clhsdb. Não consigo encontrar nenhum documento sobre quais argumentos apresentar jhsdb clhsdb.
Delthas 01 de
32

Apenas para esclarecer, não é possível usar ferramentas como jdb para anexar a JVMs já em execução>> a menos que tenham sido iniciadas no modo de depuração

na Rússia Soviética, uma fonte lê você

jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9426
vaso de planta
fonte
1
bem, essa é a resposta "suportada", mas a resposta experimental é a que eu aceitei, então pode ser feita em uma
fase
7

VisualVM não é um depurador, mas você pode obter dumps de thread e heap dumps dele que podem ser úteis no diagnóstico de alguns problemas. Os recursos mais úteis requerem JVM 5 ou 6.

sk.
fonte
o link não funciona .... talvez você deva remover o http: // antes do https: // ... Eu teria, mas não tenho reputação suficiente ainda
Newtopian
+1 VisualVM parece realmente interessante. BTW: o link está corrigido agora.
sleske
5

usando jstack (útil em caso de deadlocks) ou o plugin btrace VisualVM também pode resolver o problema

Vijay
fonte
-5

Você sempre pode usar jdb e depurar manualmente: P

OscarRyz
fonte
2
Eu sempre pensei que você não pode anexar ao jvm com jdb a menos que o jvm foi iniciado com para permitir conexões de depuração Estou errado?
hhafez
Até onde eu entendo, a opção que você mencionou é "ativar" a depuração remota do seu comando "java" (a VM). Mas você também pode usar o comando jdb. Então, em vez de java MyApp, você deveria ir como jdb MyApp (e depurar interativamente, definir pontos de interrupção, executar, parar, assistir, etc. etc.)
OscarRyz
1
Não acho que esteja correto de acordo com a página do manual do jdb - citação inicial Outra maneira de usar o jdb é anexando-o a um Java VM que já está em execução. Uma VM que será depurada com jdb deve ser iniciada com as seguintes opções: - end quote
hhafez
Com o conector correto (não suportado por enquanto) jdb pode se conectar a um processo em execução.
Thorbjørn Ravn Andersen