CMake ASAN not linking pthread

  c++, cmake, docker, gcc

I am trying to run asan using a few compiler versions to catch problems for different targets. To do this I am using custom cmake toolchain files and, to start, the official GCC Docker containers. Using gcc:11 everything works as expected, but for gcc:10 and gcc:9 I cannot link pthread at all using this custom toolchain file. I have confirmed that I can link pthread without my custom toolchain file and all works fine for the ubsan toolchain file. I suspect that I am missing some small detail. I have a minimal example that reproduces this reliably:

# asan.toolchain.cmake
set (CMAKE_C_COMPILER gcc)
set (CMAKE_CXX_COMPILER g++)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_FLAGS_INIT "-O0 -g -fsanitize=address -fno-omit-frame-pointer -fno-var-tracking-assignments")
set (CMAKE_LINKER_FLAGS_INIT "-fsanitize=address -fno-omit-frame-pointer")
set (CMAKE_BUILD_TYPE Debug)
# CMakeLists.txt
cmake_minimum_required (VERSION 3.13...3.18)

project (ASAN_TEST LANGUAGES CXX)

set (CMAME_THREAD_PREFER_PTHREADS ON)
set (THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package (Threads REQUIRED)

add_executable (test main.cpp)
target_link_libraries (test PRIVATE Threads::Threads)
// main.cpp
#include <pthread.h>

int main() {
  pthread_key_t key{};
  pthread_setspecific(key, nullptr);
}

Mounting the project inside docker with docker run -itv $(pwd):/usr/src gcc:9 and invoking cmake and make yields the following:

[email protected]: apt update && apt install -y cmake
[email protected]: mkdir build && cd build
[email protected]:/build# cmake -DCMAKE_TOOLCHAIN_FILE=/usr/src/asan.toolchain.cmake /usr/src/
-- The CXX compiler identification is GNU 9.4.0
-- Check for working CXX compiler: /usr/local/bin/g++
-- Check for working CXX compiler: /usr/local/bin/g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /build
[email protected]:/build# make VERBOSE=1
/usr/bin/cmake -S/usr/src -B/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /build/CMakeFiles /build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/build'
make -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/depend
make[2]: Entering directory '/build'
cd /build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /usr/src /usr/src /build /build /build/CMakeFiles/test.dir/DependInfo.cmake --color=
Dependee "/build/CMakeFiles/test.dir/DependInfo.cmake" is newer than depender "/build/CMakeFiles/test.dir/depend.internal".
Dependee "/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/build/CMakeFiles/test.dir/depend.internal".
Scanning dependencies of target test
make[2]: Leaving directory '/build'
make -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/build
make[2]: Entering directory '/build'
[ 50%] Building CXX object CMakeFiles/test.dir/main.cpp.o
/usr/local/bin/g++    -O0 -g -fsanitize=address -fno-omit-frame-pointer -fno-var-tracking-assignments -g   -std=gnu++14 -o CMakeFiles/test.dir/main.cpp.o -c /usr/src/main.cpp
[100%] Linking CXX executable test
/usr/bin/cmake -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
/usr/local/bin/g++  -O0 -g -fsanitize=address -fno-omit-frame-pointer -fno-var-tracking-assignments -g   CMakeFiles/test.dir/main.cpp.o  -o test
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: undefined reference to symbol '[email protected]@GLIBC_2.2.5'
/usr/bin/ld: //lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:84: test] Error 1
make[2]: Leaving directory '/build'
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/test.dir/all] Error 2
make[1]: Leaving directory '/build'
make: *** [Makefile:84: all] Error 2

If cmake is invoked with the ubsan toolchain file or without any toolchain file then this compiles and links. Note that in the output from the make invocation that -pthread is missing despite cmake reporting it as found.

For the sake of completeness here is the ubsan toolchain file:

# ubsan.toolchain.cmake
set (CMAKE_C_COMPILER gcc)
set (CMAKE_CXX_COMPILER g++)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_FLAGS_INIT "-O0 -g -fsanitize=undefined -fno-omit-frame-pointer -fno-var-tracking-assignments")
set (CMAKE_BUILD_TYPE Debug)

I appreciate any insights you may have!

Source: Windows Questions C++

LEAVE A COMMENT