- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,JDI
允许我们在调试对象应用程序中设置断点,然后通过 JDWP
获取当前的 StackFrame
。据我了解,JVMTI
用于被调试端将请求的信息通过JDWP
发送到JDI
。
是否可以从调试对象本身获取当前的 StackFrame(因此无需将其发送到调试器...调试对象将是其自己的调试器)?
例如考虑以下代码:
//client code
int a = 5;
StackFrame frame = ...
//list will contain variable "a"
List<LocalVariable> visibleVariables = frame.visibleVariables();
最佳答案
这是可能的,但有一些问题。
必须已在启动时启用 JVM 的调试。要连接您自己的 JVM,您需要使用应用程序知道的预定义端口或附加功能,这需要为最新的 JVM 显式启用自附加。
然后,由于您必须挂起要检查的线程,因此它不能是执行检查的同一个线程。所以你必须将任务委托(delegate)给不同的线程。
例如
public static void main(String[] args) throws Exception {
Object o = null;
int test = 42;
String s = "hello";
Map<String, Object> vars = variables();
System.out.println(vars);
}
// get the variables in the caller’s frame
static Map<String,Object> variables() throws Exception {
Thread th = Thread.currentThread();
String oldName = th.getName(), tmpName = UUID.randomUUID().toString();
th.setName(tmpName);
long depth = StackWalker.getInstance(
StackWalker.Option.SHOW_HIDDEN_FRAMES).walk(Stream::count) - 1;
ExecutorService es = Executors.newSingleThreadExecutor();
try {
return es.<Map<String,Object>>submit(() -> {
VirtualMachineManager m = Bootstrap.virtualMachineManager();
for(var ac: m.attachingConnectors()) {
Map<String, Connector.Argument> arg = ac.defaultArguments();
Connector.Argument a = arg.get("pid");
if(a == null) continue;
a.setValue(String.valueOf(ProcessHandle.current().pid()));
VirtualMachine vm = ac.attach(arg);
return getVariableValues(vm, tmpName, depth);
}
return Map.of();
}).get();
} finally {
th.setName(oldName);
es.shutdown();
}
}
private static Map<String,Object> getVariableValues(
VirtualMachine vm, String tmpName, long depth)
throws IncompatibleThreadStateException, AbsentInformationException {
for(ThreadReference r: vm.allThreads()) {
if(!r.name().equals(tmpName)) continue;
r.suspend();
try {
StackFrame frame = r.frame((int)(r.frameCount() - depth));
return frame.getValues(frame.visibleVariables())
.entrySet().stream().collect(HashMap::new,
(m,e) -> m.put(e.getKey().name(), t(e.getValue())), Map::putAll);
} finally {
r.resume();
}
}
return Map.of();
}
private static Object t(Value v) {
if(v == null) return null;
switch(v.type().signature()) {
case "Z": return ((PrimitiveValue)v).booleanValue();
case "B": return ((PrimitiveValue)v).byteValue();
case "S": return ((PrimitiveValue)v).shortValue();
case "C": return ((PrimitiveValue)v).charValue();
case "I": return ((PrimitiveValue)v).intValue();
case "J": return ((PrimitiveValue)v).longValue();
case "F": return ((PrimitiveValue)v).floatValue();
case "D": return ((PrimitiveValue)v).doubleValue();
case "Ljava/lang/String;": return ((StringReference)v).value();
}
if(v instanceof ArrayReference)
return ((ArrayReference)v).getValues().stream().map(e -> t(e)).toArray();
return v.type().name()+'@'+Integer.toHexString(v.hashCode());
}
当我使用选项在装有 JDK 12 的计算机上运行此程序时-Djdk.attach.allowAttachSelf -agentlib:jdwp=transport=dt_socket,server=y,suspend=n
,它打印
Listening for transport dt_socket at address: 50961
{args=[Ljava.lang.Object;@146ba0ac, s=hello, test=42, o=null}
关于java - 是否可以在调试端获取JDI当前Java中的StackFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62433660/
当我尝试在我的设备上调试时,有时会出现错误并且调试器不会在任何断点处停止。此外,该应用程序甚至无法正常启动,它只是在有点黑屏的情况下卡住,顶部有应用程序图标和名称。 错误是 Eclipse 中的弹出窗
我刚刚开始了解一些用于创建自定义调试器的 JDI。我一直在尝试将引用对象转换为真实对象,这样我就可以在不使用调用的情况下访问它们的字段或方法。我将 jar 从目标虚拟机包含到项目中,这样我就可以访问所
我正在使用 JDI 重新编码方法中的变量状态。根据教程,我没有找到如何获取 objectReference 值,例如 List、Map 或我的自定义类。它只是可以获得PrimtiveValue。 St
我正在创建一个 MethodEntryRequest,我想将此请求仅应用于两个类模式的方法,例如:- "java.*" 和 “太阳。*”。为此,我编写了以下代码。 MethodEntryRequest
我希望使用 java debug interface 构建调试器. 我的目标是设置断点并获取变量的值。 我找到了this回答接近我正在寻找的内容,我知道我必须使用以下接口(interface):- V
我已经声明并初始化了这些哈希表: Hashtable ht = new Hashtable(); ht.put("due", 2); ht.put("tre", 3); ht.put
在JDI中,有一个API可以从JPDA使用的JVM中处理的事件中排除事件。这是使用以下方法完成的: addExclusionFilter(String)排除某些模式;例如addExclusionFil
所以我正在尝试将自己投入到 JDI 中。通过首先使用 VM 命令启动被调试程序,我已经成功地将我的调试器应用程序 Hook 到我的被调试程序中: -agentlib:jdwp=transport=dt
我正在使用 JDI 来调试程序。我正在尝试更改某个对象引用中字段的值。我有 Field 对象,因为我可以通过 找到它 ObjectReference.referencetype().allFields
com.sun.jdi 是一个包,可让您获取有关正在运行的 VM 的信息、添加断点、查看堆栈帧等。 如何获取另一个实例的封闭实例?例如,下面是一些创建内部类 Garfield.Lasagna 的 4
一段时间以来,每个项目中都出现了附加的错误消息。错误发生在调试时,在调试器停止时的断点处。 Step over 和 Step into 然后不工作(一直按 step over 或 into 弹出错误消
我正在使用 JDI 调试另一个正在运行的 java 应用程序。 我所做的有效: 使用 Eclipse 运行两个应用程序。调试器使用以下 VM 选项启动: -Xdebug -Xrunjdwp:trans
我正在将我的应用程序从 JDK 7 迁移到 JDK 8。在执行过程中,我遇到了一个异常 com.sun.jdi.InvocationException occurred invoking method
我在包 com.sun.jdi 中找到了一些专为调试而设计的类,例如 VirtualMachine , 但我不能使用它,因为 Sun JDK7 中似乎不存在包。 如何使用这个包? 顺便说一句。 lib
我正在运行 Eclipse for Java。我创建了一个 XML 文件的 DOM 版本。现在我想更改文件中元素的属性。我在控制 DOM 的类中调用了一个调用方法的方法,在调试时出现了一个对话框,提示
我的代码有错误: xmldata = mContext.getResources().getStringArray(R.array.map1); for(int y = 0; y 13
我一直在编写一个使用 JDI 的 Java 客户端在远程 JVM 中创建和修改对象(通过连接到在远程 JVM 中运行的 JDWP 基于代理的服务器)。我的项目的要求之一是我无法挂起远程 JVM 中的所
我想了解如何使用 jdi 调试 java 代码,但我不知道在哪里可以获得它的源代码。是jdk里的吗?我用eclipse导入了jdk中的src.zip,但似乎没有包含jdi的信息,在哪里可以找到它? 最
我在调试时遇到了这个 eclipse 错误: org.eclipse.jdi.TimeOutException: Timeout occurred while waiting for packet 2
我正在寻找潜在的 JDI API,以便在 JVM 执行期间的任意点暂停 JVM。看着 BreakPointRequest createBreakpointRequest 方法需要一个特定的位置。是否有
我是一名优秀的程序员,十分优秀!