gpt4 book ai didi

java - 使用 jdi 构建一个简单的调试器来设置断点并检索变量的值

转载 作者:行者123 更新时间:2023-11-29 06:51:07 25 4
gpt4 key购买 nike

我希望使用 java debug interface 构建调试器.
我的目标是设置断点并获取变量的值。
我找到了this回答接近我正在寻找的内容,我知道我必须使用以下接口(interface):- VirtualMachineManagerLaunchingConnectorClassPrepareEventClassPrepareRequest。但我无法弄清楚,如何在特定行设置断点并获取变量的值,或者应该以什么顺序使用接口(interface)。

例如在下面的代码中,我如何继续使用 jdi 运行它,以便我获得变量 S

的值
import java.io.*;

class Hello {

public static void main(String args[]) {
String S = "Hello World";
int a = 12;
}
}

我正在考虑在 a = 12 行或方法 main 结束时设置调试点,以便我得到 S

最佳答案

找到这个 article有用。这里也不错example那会对你有帮助。

或者,您可以检查以下 project

这里有一个示例代码供您继续使用。

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package jdidebugger;

import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.Bootstrap;
import com.sun.jdi.ClassType;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import com.sun.jdi.connect.LaunchingConnector;
import com.sun.jdi.connect.VMStartException;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventIterator;
import com.sun.jdi.event.EventQueue;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.EventRequestManager;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author bonnie
*/
public class JdiDebugger {

/**
* @param options
* @param main
* @param classPattern
* @param methodName
* @param lineNumber
* @throws java.io.IOException
* @throws com.sun.jdi.connect.IllegalConnectorArgumentsException
* @throws com.sun.jdi.connect.VMStartException
* @throws java.lang.InterruptedException
* @throws com.sun.jdi.AbsentInformationException
* @throws com.sun.jdi.IncompatibleThreadStateException
*/
public static void onMethodExit(String options, String main, String classPattern, String methodName) throws IOException, IllegalConnectorArgumentsException, VMStartException, InterruptedException, AbsentInformationException, IncompatibleThreadStateException {

// create and launch a virtual machine
VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
LaunchingConnector lc = vmm.defaultConnector();
Map<String, Connector.Argument> env = lc.defaultArguments();
env.get("options").setValue(options);
env.get("main").setValue(main);
VirtualMachine vm = lc.launch(env);

// create a class prepare request
EventRequestManager erm = vm.eventRequestManager();
ClassPrepareRequest r = erm.createClassPrepareRequest();
r.addClassFilter(classPattern);
r.enable();

EventQueue queue = vm.eventQueue();
while (true) {
EventSet eventSet = queue.remove();
EventIterator it = eventSet.eventIterator();
while (it.hasNext()) {
Event event = it.nextEvent();
if (event instanceof ClassPrepareEvent) {
ClassPrepareEvent evt = (ClassPrepareEvent) event;
ClassType classType = (ClassType) evt.referenceType();

classType.methodsByName(methodName).forEach(new Consumer<Method>() {
@Override
public void accept(Method m) {
List<Location> locations = null;
try {
locations = m.allLineLocations();
} catch (AbsentInformationException ex) {
Logger.getLogger(JdiDebuggerOld.class.getName()).log(Level.SEVERE, null, ex);
}
// get the last line location of the function and enable the
// break point
Location location = locations.get(locations.size() - 1);
BreakpointRequest bpReq = erm.createBreakpointRequest(location);
bpReq.enable();
}
});

}
if (event instanceof BreakpointEvent) {
// disable the breakpoint event
event.request().disable();

ThreadReference thread = ((BreakpointEvent) event).thread();
StackFrame stackFrame = thread.frame(0);

// print all the visible variables with the respective values
Map<LocalVariable, Value> visibleVariables = (Map<LocalVariable, Value>) stackFrame.getValues(stackFrame.visibleVariables());
for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
vm.resume();
}
}
}
}

这就是你调用方法的方式

new jdiDebugger().onMehtodeExit("-cp <whatever your class path is>", "<name of the class that contains the main method>", "<the name of the class that you wish to debug>", "<the name of the method that you want to debug>");

关于java - 使用 jdi 构建一个简单的调试器来设置断点并检索变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47939691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com