javaflame icon indicating copy to clipboard operation
javaflame copied to clipboard

core_classes flag not working

Open beothorn opened this issue 2 years ago • 5 comments

java -javaagent:./javaAgent/build/libs/javaAgent.jar=log:INFO,core_classes,debug,filter:java.io -jar ./javaExampleApp/build/libs/javaExampleApp.jar [JAVA_AGENT] INFO Agent loaded [JAVA_AGENT] INFO logLevel :INFO flags:[core_classes] output to '/tmp/javaflame4596172070627240888/1694975820515_snap' excludes:[] filters:[java.io] Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.NoClassDefFoundError: com/github/beothorn/agent/SpanCatcher at java.base/java.io.RandomAccessFile$1.close(RandomAccessFile.java:653) at java.base/java.io.FileDescriptor.closeAll(FileDescriptor.java:355) at java.base/java.io.RandomAccessFile.close(RandomAccessFile.java:651) at java.base/java.util.zip.ZipFile$Source.close(ZipFile.java:1476) at java.base/java.util.zip.ZipFile$Source.release(ZipFile.java:1444) at java.base/java.util.zip.ZipFile$CleanableResource.run(ZipFile.java:822) at java.base/jdk.internal.ref.CleanerImpl$PhantomCleanableRef.performCleanup(CleanerImpl.java:186) at java.base/jdk.internal.ref.PhantomCleanable.clean(PhantomCleanable.java:133) at java.base/java.util.zip.ZipFile$CleanableResource.clean(ZipFile.java:746) at java.base/java.util.zip.ZipFile.close(ZipFile.java:902) at java.base/sun.launcher.LauncherHelper.getMainClassFromJar(LauncherHelper.java:606) at java.base/sun.launcher.LauncherHelper.loadMainClass(LauncherHelper.java:778) at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:686) [JAVA_AGENT] INFO Flamegraph output to '/tmp/javaflame4596172070627240888/1694975820515_snap'

beothorn avatar Sep 17 '23 18:09 beothorn

For starters, obviously instrumenting native methods fail with a core dump.

Exception in thread "main" *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message Outstanding error when calling method in invokeJavaAgentMainMethod at ./src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 627
*** java.lang.instrument ASSERTION FAILED ***: "success" with message invokeJavaAgentMainMethod failed at ./src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 466
*** java.lang.instrument ASSERTION FAILED ***: "result" with message agent load/premain call failed at ./src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 429
FATAL ERROR in native method: processing of -javaagent failed, processJavaStart failed
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x9a02c4]  jni_FatalError+0x74
V  [libjvm.so+0xb05e64]  JvmtiExport::post_vm_initialized()+0x3f4
V  [libjvm.so+0xf8003e]  Threads::create_vm(JavaVMInitArgs*, bool*)+0x85e
V  [libjvm.so+0x9a2332]  JNI_CreateJavaVM+0x52
C  [libjli.so+0x4673]  JavaMain+0x93
C  [libjli.so+0x844d]  ThreadJavaMain+0xd
C  [libc.so.6+0x9ca94]
./buildAndRunOnceRelativeFolder.sh: line 23: 72833 Aborted                 (core dumped) java -javaagent:./javaflame/build/libs/javaAgent-java21.jar=out:./out,"$*" -jar ./javaSortingAlgorithms/build/libs/javaSortingAlgorithms.jar

beothorn avatar Nov 01 '24 21:11 beothorn

Exception in thread "Javaflame Snapshot" java.lang.NoClassDefFoundError: com/github/beothorn/agent/recorder/FunctionCallRecorderWithValueCapturing
	at java.base/java.io.File.getPrefixLength(File.java:205)
	at java.base/java.io.UnixFileSystem.isAbsolute(UnixFileSystem.java:143)
	at java.base/java.io.UnixFileSystem.resolve(UnixFileSystem.java:153)
	at java.base/java.io.File.getAbsolutePath(File.java:561)
	at com.github.beothorn.agent.MethodInstrumentationAgent.writeSnapshotToFile(MethodInstrumentationAgent.java:458)
	at com.github.beothorn.agent.MethodInstrumentationAgent.lambda$premainInternal$3(MethodInstrumentationAgent.java:237)
	at java.base/java.lang.Thread.run(Thread.java:1583)

beothorn avatar Nov 01 '24 21:11 beothorn

Loading classes on base classloader gets rid of the issues, but doesn`t instrument the class:

Class<FunctionCallRecorderWithValueCapturing> class1 = FunctionCallRecorderWithValueCapturing.class;
            Class<FunctionCallRecorder> class2 = FunctionCallRecorder.class;
            Class<Log> class3 = Log.class;
            Class<Log.LogLevel> class4 = Log.LogLevel.class;
            Class<MethodInstrumentationAgent> class5 = MethodInstrumentationAgent.class;
            Class<Span> class6 = Span.class;
            ClassInjector.UsingUnsafe.ofBootLoader().inject(Map.of(
                    new TypeDescription.ForLoadedType(class1), ClassFileLocator.ForClassLoader.read(class1),
                    new TypeDescription.ForLoadedType(class2), ClassFileLocator.ForClassLoader.read(class2),
                    new TypeDescription.ForLoadedType(class3), ClassFileLocator.ForClassLoader.read(class3),
                    new TypeDescription.ForLoadedType(class4), ClassFileLocator.ForClassLoader.read(class4),
                    new TypeDescription.ForLoadedType(class5), ClassFileLocator.ForClassLoader.read(class5),
                    new TypeDescription.ForLoadedType(class6), ClassFileLocator.ForClassLoader.read(class6)
            ));

beothorn avatar Nov 01 '24 22:11 beothorn

This needs more investigation. In my experiments I could not intercept java.io.File. Maybe core_classes should be removed as an option.

beothorn avatar Nov 05 '24 20:11 beothorn

The issue is that at the point the agent is loaded, many classes were already loaded, including java.io.File. This can be verified by adding this code to the agent:

Class[] allLoadedClasses = instrumentation.getAllLoadedClasses();
for (Class loadedClass : allLoadedClasses) {
    System.out.println("Loaded " + loadedClass.getName());
}

There is no easy fix for this, but it also means core_classes may work with other internal classes.
So, just the test needs to change to check if it works.

beothorn avatar Nov 10 '24 22:11 beothorn