You could process your binary classes looking for fdiv operations, inserting a check for divide by zero.
Java:
return x.getFloat() / f2;
javap output:
0: aload_0
1: invokevirtual #22; //Method DivByZero$X.getFloat:()F
4: fload_1
5: fdiv
6: freturn
Replacement code that throws a ArithemticException for divide-by-zero:
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
This processing can be done using bytecode manipulation APIs like ASM. This isn't really trivial, but it isn't rocket science either.
If all you want is monitoring (rather than changing the operation of the code), then a better approach might be to use a debugger. I'm not sure what debuggers would allow you to write an expression to catch what you're looking for, but it isn't difficult to write your own debugger. The Sun JDK provides the JPDA and sample code showing how to use it (unzip jdk/demo/jpda/examples.jar).
Sample code that attaches to a socket on 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);
}
}