Skip to content

Instantly share code, notes, and snippets.

View brianduff's full-sized avatar

Brian Duff brianduff

View GitHub Profile
// Called when a breakpoint is hit.
void JNICALL BreakpointCallback(jvmtiEnv *jvmti_env, JNIEnv *jni, jthread thread, jmethodID method, jlocation location) {
// Get hold of the parameter. In this example, we just get the first parameter.
// Which parameter is first depends on whether this is a static or instance method.
// For instance methods, the first parameter is a synthetic parameter representing
// the current instance of the class. So here, we get the first "real" parameter.
int parameterPos = 1;
jobject the_parameter;
assert(JVMTI_ERROR_NONE == (*jvmti_env)->GetLocalObject(jvmti_env, thread, 0, parameterPos, &the_parameter));
void JNICALL ClassPrepareCallback(jvmtiEnv *jvmti_env, JNIEnv *jni, jthread thread, jclass klass) {
// Avoid re-entrancy, and return early if we already attached.
if (in_prepare || attached) {
return;
}
in_prepare = true;
jclass clazz = (*jni)->FindClass(jni, classConfig->name);
// In case we don't find the class, don't throw an exception
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
char *option = strtok(options, ",");
// ...
// Load the config file using options from `option`. Also parse out an option for
// a log file to write to.
// ..
fprintf(stderr, "mlogagent: Loaded agent\n");
someMethod: /foo
trace: <- someMethod <- run <- main
someMethod: /bar
trace: <- someMethod <- run <- main
# This is the class I care about
- frodo/Test
# And this is a method I want to log with its super ugly JVM signature
- someMethod(Lfrodo/Test$RealFile;)Ljava/lang/String;
# Please show me an abbreviated stack trace for each call
- showTrace: true
# And use the getPath() method to convert the parameter to a String
- displayMethod: getPath
package frodo;
public class Example {
public static void main(String[] args) {
new Test().run();
}
public void run() {
System.out.println(someMethod(new RealFile("/foo")));
System.out.println(someMethod(new RealFile("/bar")));
public void doSomethingInteresting(Thingy t) {
if (Config.shoudLogInterestingThings()) {
LOG.info("doSomethingInteresting(%s)", t);
}
// Actually do something interesting
}
type RecordIndex = i32;
type ContentIndex = i32;
type Bytes = Vec<u8>;
/// IJ has the notion of "enumerations" which are basically fast bimaps between a value of
/// arbitrary type and an integer, and support automatically adding new values which
/// get an auto-incremented integer value.
type Enumeration<A> = BiMap<A, i32>;
for (IjProjectElement dep : moduleDeps.keySet()) {
if (dep instanceof IjLibrary) {
referencedLibraries.add((IjLibrary) dep);
}
}
moduleDeps.keySet().stream()
.filter(dep -> dep instanceof IjLibrary)
.map(library -> (IjLibrary) library)
.forEach(referencedLibraries::add);