Как можно использовать Java Debug Interface для отслеживания рекурсивных вызовов, которые, вероятно, будут сделаны при оценке выражения Main.reverseString ( args[0] )
в файле Main.java
?
Вот файл Main.java
:
public class Main
{
public static void main ( String [] args )
{
System.out.println ( "args[0] ..... " + args[0] ) ;
String reversed = Main.reverseString ( args[0] ) ;
System.out.println ( "reversed .... " + reversed ) ;
} // main
public static String reverseString ( String s )
{
if ( s.length() <= 1 )
return s ;
return ( (new StringBuilder(reverseString(s.substring(1))))
.append(s.charAt(0)).toString() ) ;
} // reverseString
} // Main
Моя программа трассировки (RecursionTracer
) показана ниже:
import com.sun.jdi.* ;
import com.sun.jdi.connect.* ;
import com.sun.jdi.request.* ;
import com.sun.jdi.event.* ;
import java.util.* ;
public class RecursionTracer
{
public static void main ( String [] args ) throws Exception
{
LaunchingConnector launchingConnector
= Bootstrap.virtualMachineManager().defaultConnector() ;
Map<String, Connector.Argument> env
= launchingConnector.defaultArguments() ;
env.get("main").setValue ( Main.class.getName() ) ;
VirtualMachine vm = launchingConnector.launch(env) ;
ClassPrepareRequest classPrepareRequest
= vm.eventRequestManager().createClassPrepareRequest() ;
classPrepareRequest.addClassFilter ( Main.class.getName() ) ;
classPrepareRequest.enable() ;
EventSet eventSet = null ;
do
{
eventSet = vm.eventQueue().remove() ;
for ( Event event : eventSet )
{
if ( event instanceof ClassPrepareEvent )
{
MethodEntryRequest methodEntryRequest
= vm.eventRequestManager().createMethodEntryRequest() ;
methodEntryRequest.addClassFilter ( Main.class.getName() ) ;
methodEntryRequest.enable() ;
} // if ClassPrepareEvent
if ( event instanceof MethodEntryEvent )
{
System.out.println ( "\n--------------------------------------" ) ;
MethodEntryEvent methodEntryEvent = (MethodEntryEvent) event ;
com.sun.jdi.Method method = methodEntryEvent.method () ;
System.out.println ( "MethodEntryEvent has occurred ..." ) ;
System.out.println ( methodEntryEvent ) ;
System.out.println ( method ) ;
System.out.println ( "======================================\n" ) ;
} // if MethodEntryEvent
vm.resume() ;
} // for each event
}
while ( eventSet != null ) ;
} // main
} // RecursionTracer
Я компилирую Main.java
и RecursionTracer.java
следующим образом:
del *.class
D:\Java\JDK-11~1.1\bin\javac.exe -g Main.java RecursionTracer.java -Xlint:unchecked
Когда я запускаю RecursionTracer
, его вывод:
D:\>D:\Java\JDK-11~1.1\bin\java.exe RecursionTracer
--------------------------------------
MethodEntryEvent has occurred ...
MethodEntryEvent@Main:5 in thread main
Main.main(java.lang.String[])
======================================
Exception in thread "main" com.sun.jdi.VMDisconnectedException
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:200)
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:97)
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:83)
at RecursionTracer.main(RecursionTracer.java:26)
Я ожидал, что MethodEntryEvent
s будет происходить каждый раз, когда вводится метод Main.reverseString
, но, как видно из вышеприведенного вывода, единственный MethodEntryEvent
- это когда выполнение входит в Main.main
. Почему также не отображается MethodEntryEvent
s для Main.reverseString
? Кроме того, как я могу получить такие MethodEntryEvent
с для отображения? Наконец, было бы неплохо увидеть аргумент, который передается Main.reverseString
при каждом вызове этого метода.