jvm-profiling-tools / honest-profiler

A sampling JVM profiler without the safepoint sample bias
https://github.com/RichardWarburton/honest-profiler/wiki
MIT License
1.25k stars 146 forks source link

can't load liblagent.so - undefined symbol #193

Closed nevgeniev closed 6 years ago

nevgeniev commented 7 years ago

hi,

i've tried to compile and load profiler with jdk 1.8.121 got this upon load: Could not find agent library honest-profiler/honest-profiler/build/liblagent.so in absolute path, with error: honest-profiler/honest-profiler/build/liblagent.so: undefined symbol: _ZNVSt6atomicIPN3map9HashTableEE5storeES2_St12memory_order

daodennis-zz commented 7 years ago

What's your -agentpath look like and can you run stat (if this is a linux system) on the location of where liblagent.so is as the user your java program is running?

This is the How to Run for quick reference

nevgeniev commented 7 years ago

I can ldd & stat the library as I built it from source... the thing is I built it with old gcc (4.4.7) /libc... not sure to what degree it could affect the run.. I'm using absolute path.. the problem is not with the library but rather with unknown symbol referenced by library

ikavalio commented 7 years ago

Hey @nevgeniev, I don't think you can compile libagent with gcc's younger than 4.5. I personally used 4.6+ for the development.

nevgeniev commented 7 years ago

this is true unless you define 'nullptr'... once you do you can compile in with gcc older than 4.6

ikavalio commented 7 years ago

@nevgeniev, I believe it's more complicated than just nullptr. Since you're using gcc-4.4 which doesn't have standard c++ atomic's library, cstdatomic will be used instead.

#if __GNUC__ == 4 && __GNUC_MINOR__ < 6 && !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__clang__)
#   include <cstdatomic>
#else
#   include <atomic>
#endif

Unfortunately it doesn't work well with std::atomic<X> where X is not primitive type, even a pointer to it. Code within concurrent_map.h unfortunately contains:

std::atomic<Job*> job;  
std::atomic<HashTable*> current;

That's why runtime linker is complaining about undefined symbols. It's easy to find them all BTW:

?> ~/w/honest-profiler on master ? nm build/liblagent.so | grep memory_order | grep -e '\bU\b'                    19:20:04
                 U _ZNVSt6atomicIPN3map3JobEE5storeES2_St12memory_order
                 U _ZNVSt6atomicIPN3map9HashTableEE5storeES2_St12memory_order

The only simple solution that can fix this issue is to replace this two variables' type to std::atomic_address (std::atomic<void*>) which is defined in cstdatomic - cstdatomic and cast it to appropriate type like Job* when needed.

I can try to implement this, but don't know how long will it take.

nitsanw commented 6 years ago

Given the fixing PR has been merged I'm closing. Please re-open if the problem persists.