您可以处理您的二进制类以查找 fdiv 操作,插入一个除以零的检查。
Java:
return x.getFloat() / f2;
javap 输出:
0: aload_0
1: invokevirtual #22; //Method DivByZero$X.getFloat:()F
4: fload_1
5: fdiv
6: freturn
为被零除抛出 ArithhemticException 的替换代码:
0: aload_1
1: invokevirtual #22; //Method DivByZero$X.getFloat:()F
4: fstore_2
5: fload_0
6: fconst_0
7: fcmpl
8: ifne 21
11: new #32; //class java/lang/ArithmeticException
14: dup
15: ldc #34; //String / by zero
17: invokespecial #36; //Method java/lang/ArithmeticException."<init>":(Ljava/lang/String;)V
20: athrow
21: fload_2
22: fload_0
23: fdiv
24: freturn
这个处理可以使用像ASM这样的字节码操作API来完成。这并非微不足道,但也不是火箭科学。
如果您想要的只是监控(而不是更改代码的操作),那么更好的方法可能是使用调试器。我不确定哪些调试器可以让您编写表达式来捕获您要查找的内容,但编写自己的调试器并不难。 Sun JDK 提供了JPDA 和演示如何使用它的示例代码(解压缩 jdk/demo/jpda/examples.jar)。
附加到 localhost 上的套接字的示例代码:
public class CustomDebugger {
public static void main(String[] args) throws Exception {
String port = args[0];
CustomDebugger debugger = new CustomDebugger();
AttachingConnector connector = debugger.getConnector();
VirtualMachine vm = debugger.connect(connector, port);
try {
// TODO: get & use EventRequestManager
vm.resume();
} finally {
vm.dispose();
}
}
private AttachingConnector getConnector() {
VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();
for (Connector connector : vmManager.attachingConnectors()) {
System.out.println(connector.name());
if ("com.sun.jdi.SocketAttach".equals(connector.name())) {
return (AttachingConnector) connector;
}
}
throw new IllegalStateException();
}
private VirtualMachine connect(AttachingConnector connector, String port)
throws IllegalConnectorArgumentsException, IOException {
Map<String, Connector.Argument> args = connector.defaultArguments();
Connector.Argument pidArgument = args.get("port");
if (pidArgument == null) {
throw new IllegalStateException();
}
pidArgument.setValue(port);
return connector.attach(args);
}
}