clojure-goes-fast / clj-async-profiler

Embedded high-precision Clojure profiler
http://clojure-goes-fast.com/kb/profiling/clj-async-profiler/
402 stars 17 forks source link

Document dependencies / vague init error #3

Closed lischenko closed 6 years ago

lischenko commented 6 years ago

I was having an issue trying to use the profiler:

> (prof/start {})
AgentLoadException Failed to load agent library  sun.tools.attach.LinuxVirtualMachine.execute (LinuxVirtualMachine.java:224)

1. Unhandled com.sun.tools.attach.AgentLoadException
   Failed to load agent library

  LinuxVirtualMachine.java:  224  sun.tools.attach.LinuxVirtualMachine/execute
HotSpotVirtualMachine.java:   58  sun.tools.attach.HotSpotVirtualMachine/loadAgentLibrary
HotSpotVirtualMachine.java:   88  sun.tools.attach.HotSpotVirtualMachine/loadAgentPath
NativeMethodAccessorImpl.java:   -2  sun.reflect.NativeMethodAccessorImpl/invoke0
NativeMethodAccessorImpl.java:   62  sun.reflect.NativeMethodAccessorImpl/invoke
DelegatingMethodAccessorImpl.java:   43  sun.reflect.DelegatingMethodAccessorImpl/invoke
               Method.java:  498  java.lang.reflect.Method/invoke
            Reflector.java:   93  clojure.lang.Reflector/invokeMatchingMethod
            Reflector.java:   28  clojure.lang.Reflector/invokeInstanceMethod
                  core.clj:  109  clj-async-profiler.core/attach-agent
                  core.clj:  103  clj-async-profiler.core/attach-agent
                  core.clj:  124  clj-async-profiler.core/start
                  core.clj:  116  clj-async-profiler.core/start
                  core.clj:  121  clj-async-profiler.core/start
                  core.clj:  116  clj-async-profiler.core/start
                      REPL:  485  my.ns/eval23126

So after some debugging it boiled down to:

> (System/load "/tmp/clj-async-profiler/libasyncProfiler-linux.so")
UnsatisfiedLinkError /tmp/clj-async-profiler/libasyncProfiler-linux.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /tmp/clj-async-profiler/libasyncProfiler-linux.so)  java.lang.ClassLoader$NativeLibrary.load (ClassLoader.java:-2)

and

$ ldd /tmp/clj-async-profiler/libasyncProfiler-linux.so 
ldd: warning: you do not have execution permission for `/tmp/clj-async-profiler/libasyncProfiler-linux.so'
/tmp/clj-async-profiler/libasyncProfiler-linux.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /tmp/clj-async-profiler/libasyncProfiler-linux.so)
    linux-vdso.so.1 =>  (0x00007ffdeb1ef000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f7209974000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7209757000)
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f720944f000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f72091cb000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7208fb5000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f7208c20000)
    /lib64/ld-linux-x86-64.so.2 (0x0000562f0bec9000)

The system I run this on has a bit older version of libc.

It would be great to make this kind of errors more transparent, perhaps by having more than just "Failed to load agent library" message and/or documenting the required dependencies in the wiki.

lischenko commented 6 years ago

Oh, and in case anyone is wondering, the quick and dirty fix for that is to follow https://github.com/jvm-profiling-tools/async-profiler#building to build the .so locally and then replace /tmp/clj-async-profiler/libasyncProfiler-linux.so with it.

alexander-yakushev commented 6 years ago

Thanks for reporting! I've pushed a possible improvement as 0.1.3-SNAPSHOT. Could you try it and confirm? I can't test it myself easily.

Regarding documenting the dependencies explicitly, I think it should better be on async-profiler side. Besides, if the hack I've pushed works, people will know about the mismatched dependency from the exception.

BTW, you can do (reset! prof/async-profiler-agent-path "/path/to/custom/agent.so") instead of replacing the file in the tempdir.

lischenko commented 6 years ago

Thanks for making the change, works as expected with 0.1.3-SNAPSHOT:

myns> (clojure.core/require '[clj-async-profiler.core :as prof])
nil
myns> (prof/start {})
UnsatisfiedLinkError /tmp/clj-async-profiler/libasyncProfiler-linux.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /tmp/clj-async-profiler/libasyncProfiler-linux.so)  java.lang.ClassLoader$NativeLibrary.load (ClassLoader.java:-2)
alexander-yakushev commented 6 years ago

Thank you!