When linked "properly" (explained further), both function calls below block indefinitely on pthread calls implementing cv.notify_one and cv.wait_for:
// let's call it odr.cpp, which forms libodr.so
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void Notify() {
  std::chrono::milliseconds(100);
  std::unique_lock<std::mutex> lock(mtx);
  ready = true;
  cv.notify_one();
}
void Get() {
  std::unique_lock<std::mutex> lock(mtx);
  cv.wait_for(lock, std::chrono::milliseconds(300));
}
when shared library above is used in following application:
// let's call it test.cpp, which forms a.out
int main() {
  std::thread thr([&]() {
    std::cout << "Notify\n";
    Notify();
  });
  std::cout << "Before Get\n";
  Get();
  std::cout << "After Get\n";
  thr.join();
}
Problem reproduces only when linking libodr.so:
- with g++
 - with gold linker
 - providing 
-lpthreadas dependency 
with following versions of relevant tools:
Linux Mint 18.3 Sylviabinutils 2.26.1-1ubuntu1~16.04.6g++ 4:5.3.1-1ubuntu1libc6:amd64 2.23-0ubuntu10
so that we end up with:
__pthread_key_createdefined as WEAK symbol in PLT- no 
libpthread.soas dependency in ELF 
as shown here:
$ g++ -fPIC -shared -o build/libodr.so build/odr.cpp.o -fuse-ld=gold -lpthread && readelf -d build/libodr.so | grep Shared && readelf -Ws build/libodr.so | grep -m1 __pthread_key_create
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    10: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __pthread_key_create
On the other hand, with any of the following we experience no bug:
- clang++
 - bfd linker
 - no explicit 
-lpthread -lpthreadbut with-Wl,--no-as-needed
note: this time we have either:
NOTYPEand nolibpthread.sodependencyWEAKandlibpthread.sodependency
as shown here:
$ clang++ -fPIC -shared -o build/libodr.so build/odr.cpp.o -fuse-ld=gold -lpthread && readelf -d build/libodr.so | grep Shared && readelf -Ws build/libodr.so | grep -m1 __pthread_key_create && ./a.out 
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    24: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __pthread_key_create@GLIBC_2.2.5 (7)
$ g++ -fPIC -shared -o build/libodr.so build/odr.cpp.o -fuse-ld=bfd -lpthread && readelf -d build/libodr.so | grep Shared && readelf -Ws build/libodr.so | grep -m1 __pthread_key_create && ./a.out 
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    14: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __pthread_key_create
$ g++ -fPIC -shared -o build/libodr.so build/odr.cpp.o -fuse-ld=gold && readelf -d build/libodr.so | grep Shared && readelf -Ws build/libodr.so | grep -m1 __pthread_key_create && ./a.out  0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    18: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __pthread_key_create
$ g++ -fPIC -shared -o build/libodr.so build/odr.cpp.o -fuse-ld=gold -Wl,--no-as-needed -lpthread && readelf -d build/libodr.so | grep Shared && readelf -Ws build/libodr.so | grep -m1 __pthread_key_create && ./a.out 
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    10: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __pthread_key_create@GLIBC_2.2.5 (4)
Complete example to compile/run can be found here: https://github.com/aurzenligl/study/tree/master/cpp-pthread
What breaks shlib using pthread when __pthread_key_create is WEAK and no libpthread.so dependency in ELF can be found? Does the dynamic linker take the pthread symbols from libc.so (stubs) instead of libpthread.so?