The undefined reference issue of Clang AddressSanitizer

I try to utilize Clang AddressSanitizer in NixOS and I meet the following error.

[2/2] Linking CXX executable app.out
FAILED: app.out
: && /nix/store/99kjyyazbp2fwimhksz9x0imi59mp359-clang-wrapper-14.0.1/bin/clang++   CMakeFiles/app.out.dir/src/main.cpp.o -o app.out   && :
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: /nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: DWARF error: invalid or unhandled FORM value: 0x23
CMakeFiles/app.out.dir/src/main.cpp.o: in function `_GLOBAL__sub_I_main.cpp':
main.cpp:(.text.startup+0x9): undefined reference to `__asan_before_dynamic_init'
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: main.cpp:(.text.startup+0x33): undefined reference to `__asan_after_dynamic_init'
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: CMakeFiles/app.out.dir/src/main.cpp.o: in function `asan.module_ctor':
main.cpp:(.text.asan.module_ctor+0x2): undefined reference to `__asan_init'
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: main.cpp:(.text.asan.module_ctor+0x7): undefined reference to `__asan_version_mismatch_check_v8'
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: main.cpp:(.text.asan.module_ctor+0x18): undefined reference to `__asan_register_globals'
/nix/store/0q9hm42fapihzj1d64nxqmbml7fpb2d6-binutils-2.38/bin/ld: CMakeFiles/app.out.dir/src/main.cpp.o: in function `asan.module_dtor':
main.cpp:(.text.asan.module_dtor+0xe): undefined reference to `__asan_unregister_globals'
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
make: *** [Makefile:13: build] Error 1

To reproduces the error, I use the following codes.

$ tree .
├── CMakeLists.txt
├── Makefile
├── src
│   └── main.cpp
└── toolchain.nix
$ cat toolchain.nix
with import <nixpkgs> {};

(mkShell.override { stdenv = llvmPackages_14.stdenv; }) {
  name = "app";

  buildInputs = with pkgs; [
    gdb
    cmake
    ninja
  ];
}
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

set(project_name "app")
set(src_dir      "src")

project(${project_name})

set(CMAKE_CXX_STANDARD          17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include_directories("${CMAKE_CURRENT_LIST_DIR}")

file(GLOB_RECURSE SRC "${src_dir}/*.cpp")

add_executable(${project_name}.out ${SRC})

target_compile_options(${project_name}.out PRIVATE -O1 -g -fsanitize=address)
target_link_libraries(${project_name}.out)  
$ make build; cd build; cmake -DCMAKE_C_COMPILER="clang" -DCMAKE_CXX_COMPILER="clang++" -GNinja ..; ninja;
$ cat src/main.cpp
int main(void) {
  int* a = (int*)malloc(sizeof(int) * 100);
  return 0;
}
$ nix-shell toolchain.nix
[nix-shell] $ make default

Finally, the system will occurs the same error.

I guess it seems the system use the GNU Binutils by default and LLVM doesn’t use it, so it occurs the error. If my assumption is right, do I need to rewrite the toolchain.nix ? or just add some linker flags in the CMakeLists.txt

Any idea ? thanks.

target_compile_options(${project_name}.out PRIVATE -O1 -g -fsanitize=address)

You need to add -fsanitize=address to both compiler and linker options. I’m not cmake expert but I think you are adding it only to compiler options.