Debug remoto Java, come funziona tecnicamente?

Mi piacciono molto le funzionalità di debug remoto della JVM. Ma mi chiedo come funzioni internamente.

Il mio presupposto: è fatto attraverso una funzione JVM in cui il processo in esecuzione sta scaricando / utilizzando il codice sorgente dal remote-debugger collegato (come IDE) Conosce la linea dello stack-trace corrente e poi può passare al rispettivo IDE punto di rottura. La comunicazione di stack-trace e introspection dello stato dell’applicazione viene quindi eseguita tramite socket o shared-memory (impostazione del debugger remoto).

Qualcuno ha link / risorse interessanti su questo?

Le funzionalità di debug della JVM sono fornite tramite Java Platform Debugger Architecture (JPDA) .

Lo stesso JPDA è composto da quanto segue:

  • Java Virtual Machine Tool Interface (JVM TI) – l’interfaccia di programmazione nativa per gli strumenti da utilizzare. Questa interfaccia consente l’ispezione statale e aiuta a controllare il stream di esecuzione all’interno del debuggee.
  • Java Debug Wire Protocol (JDWP) – utilizzato per definire la comunicazione tra i processi del debugger e del debuggee.
  • Java Debug Interface (JDI): questa interfaccia consente agli sviluppatori di strumenti di scrivere applicazioni di debugger remote.

Lo schema elencato nella struttura dell’architettura JPDA è un buon punto di partenza. Altri posti da cercare sarebbero le guide elencate nella pagina JPDA .

L’architettura di debug di Java si chiama JPDA. Probabilmente vorresti leggere la documentazione di JPDA. In particolare, la sezione Walk-through fornisce un esempio di un IDE che si interfaccia con il JDI per ottenere un valore sullo stack.

Il debug di Eclipse inizia con ciò che viene definito come agenti.

La JVM, che esegue le sorgenti “.class” soddisfatte, ha una funzione che consente di iniettare in JVM le librerie esterne (scritte in Java o C ++) durante il runtime. Queste librerie esterne sono indicate come agenti e hanno la possibilità di modificare il contenuto dei file .class eseguiti. Questi agenti hanno accesso alle funzionalità della JVM che non sono accessibili da un normale codice Java in esecuzione all’interno della JVM e possono essere utilizzate per fare cose interessanti come iniettare e modificare il codice sorgente in esecuzione, la profilazione ecc. Alcuni strumenti come JRebel (usato per la sostituzione a caldo del codice) utilizza questa funzionalità per ottenere la loro magia.

E per passare un agente Lib a una JVM, lo fai tramite gli argomenti di avvio, usando il –

agentlib:libname[=options] 

In realtà stavamo passando un agente Lib chiamato jdwp alla JVM con Tomcat. Jdwp è un’implementazione specifica JVM opzionale del JDWP (Java Debug Wire Protocol) che viene utilizzata per definire la comunicazione tra un debugger e una JVM in esecuzione. È l’implementazione, se presente viene fornita come libreria nativa della JVM come jdwp.so o jdwp.dll

Quindi, che cosa fa? In termini semplici, l’agente jdwp che passiamo serve fondamentalmente la funzione di essere un collegamento tra l’istanza JVM che esegue un’applicazione e un Debugger (che può trovarsi sia remoto che locale). Poiché è una libreria di agenti, ha la capacità di intercettare il codice in esecuzione, creare un ponte tra la JVM e un debugger e avere la funzionalità di un debugger applicata sulla JVM. Poiché nell’architettura JVM, la funzionalità di debug non si trova all’interno della JVM stessa ma viene estratta in strumenti esterni (che vengono definiti correttamente come debugger), questi strumenti possono risiedere sulla macchina locale che esegue la JVM in fase di debug o di esecuzione. da una macchina esterna. È questa architettura modulare disaccoppiata che ci consente di avere una JVM in esecuzione su una macchina remota e l’utilizzo del JDWP, di avere un debugger remoto in grado di comunicare con essa.

Questo è il modo in cui Eclipse debugger funziona in breve.