DiSL is a dynamic program-analysis framework based on Java bytecode instrumentation. In DiSL, developers write instrumentation code in the form of code snippets, based on aspect-oriented programming (AOP) principles that allow a concise implementation of runtime monitoring tools.
DiSL allows developers to specify where a code snippet shall be woven through markers (specifying which parts of a method to instrument, such as method bodies, basic blocks, etc.), annotations (specifying where a code snippet must be inserted wrt. a marker, e.g., before or after method bodies), scope (specifying which classes or methods shall be instrumented based on a pattern-matching scheme), and guards (predicate methods enabling the
evaluation of conditionals at instrumentation-time to determine whether a code snippet should be woven into the method being instrumented or not). Code snippets and guards have access to context information provided via
method arguments. Context information can be either static (i.e., static information limited to constants) or dynamic (i.e., including local variables and the operand stack). Dynamic context information can be accessed only by code snippets. DiSL supports also synthetic local variables (enabling data passing between different code snippets woven into the same method body) and thread-local variables (implemented by additional instance fields in java.lang.Thread).
DiSL performs the instrumentation in a separate JVM process, often called the DiSL server. A native JVMTI agent attached to the observed JVM intercepts classloading, sending each loaded class to the DiSL server. There, the instrumentation logic determines which methods to instrument to collect the desired metrics. Instrumented classes are then sent back to the observed JVM. The DiSL weaver guarantees full bytecode coverage of an analysis. In particular, DiSL enables the instrumentation of classes in the Java class library, which are notoriously hard to instrument.1 2
DiSL ensures comprehensive code coverage (i.e., all code that has a bytecode representation can be analyzed) and features a partial evaluator to optimize inserted instrumentation code, as well as a controller for adaptive analyses that changes the instrumentation at runtime. Thanks to the Dispatch API, DiSL is able to add or remove instrumentation from loaded classes at runtime. While DiSL performs instrumentation in a separate process, it provides reflective information on the supertypes of each class being instrumented.
Downloads
DiSL is hosted as open-source project on GitLab.
You can find more information on DiSL on the project website.
Key Publications
[1] Lukás Marek, Alex Villazón, Yudi Zheng, Danilo Ansaloni, Walter Binder, Zhengwei Qi: DiSL: A Domain-specific Language for Bytecode Instrumentation. AOSD 2012: 239-250 [pdf]
[2] Andrea Rosà, Walter Binder: Optimizing Type-specific Instrumentation on the JVM with Reflective Supertype Information. J. Vis. Lang. Comput. 49: 29-45 (2018) [pdf]
[3] Andrea Rosà, Eduardo Rosales, Walter Binder: Accurate Reification of Complete Supertype Information for Dynamic Analysis on the JVM. GPCE 2017: 104-116 [pdf][video][slides]
References
1 W. Binder, J. Hulaas, and P. Moret. “Advanced Java Bytecode Instrumentation”. PPPJ 2007.
2 S. Kell, D. Ansaloni, W. Binder, and L. Marek. “The JVM is Not Observable Enough (and What to Do About It)”. VMIL 2012.