1

I'm trying to compile a program using -fsanitize=undefined using the conda g++ compiler. I'm running into `__ubsan_handle_type_mismatch' linker errors. I've used the flags in the compiles and the linking as suggested in:

including adding -lubsan to the end of the link and compile commands which I know isn't recommended but I had no success. I've also made sure my LD_LIBRARY_PATH is empty so that there isn't any trouble coming from that aspect.

A minimal example problem including the configuration of my python environment is below

vehicles.h

#include<string>
#include<memory>

#ifndef VEHICLES
#define VEHICLES

class vehicle{

    public:
        vehicle( );

        std::shared_ptr< vehicle > buildVehicle( const std::string & _type );

    protected:

        std::string type;

        unsigned int wheel_count;

};

class truck : public vehicle{

    public:
        truck( );

};

#endif

vehicles.cpp

#include "vehicles.h"

vehicle::vehicle( ){

    return;
}

std::shared_ptr< vehicle > vehicle::buildVehicle( const std::string &_type ){

    if ( _type.compare( "truck" ) ){

        return std::make_shared< vehicle >( );

    }

    return NULL;

}

truck::truck( ){

    type = "truck";
    wheel_count = 4;

}

test.cpp

#include "vehicles.h"
#include<iostream>

int main( ){

    //Build a truck
    std::shared_ptr< vehicle > truck = vehicle( ).buildVehicle( "truck" );

    std::cout << "Built a truck\n";

}

makefile

EXECUTABLE = eval
OBJECTS = test.o vehicles.o
INCS = -I. -I/home/nathan/anaconda3/include
LIBS = -L/home/nathan/anaconda3/lib
FLAGS = -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr

eval: $(OBJECTS)
        $(CXX) $(INCS) $(LIBS) -o $@ $^ $(FLAGS)

test.o: test.cpp vehicles.h
        $(CXX) $(INCS) $(LIBS) -c $< $(FLAGS)

vehicles.o: vehicles.cpp vehicles.h
        $(CXX) $(INCS) $(LIBS) -c $< $(FLAGS)

clean:
        rm -f $(EXECUTABLE)
        rm -f $(OBJECTS)

.PHONY: all clean

My conda environment YAML file is:

name: compile
channels:
  - anaconda
  - conda-forge
  - defaults
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=1_gnu
  - binutils=2.32=he1b5a44_3
  - binutils_impl_linux-64=2.31.1=h7fc9f1b_5
  - binutils_linux-64=2.31.1=h6176602_9
  - bzip2=1.0.8=h516909a_3
  - c-ares=1.16.1=h516909a_3
  - c-compiler=1.1.1=h516909a_0
  - ca-certificates=2020.6.20=hecda079_0
  - certifi=2020.6.20=py38h32f6830_0
  - cmake=3.18.2=h5c55442_0
  - cxx-compiler=1.1.1=hc9558a2_0
  - expat=2.2.9=he1b5a44_2
  - gcc_impl_linux-64=7.3.0=habb00fd_1
  - gcc_linux-64=7.3.0=h553295d_9
  - gxx_impl_linux-64=7.3.0=hdf63c60_1
  - gxx_linux-64=7.3.0=h553295d_9
  - hdf5=1.12.0=nompi_h54c07f9_101
  - icu=67.1=he1b5a44_0
  - jpeg=9d=h516909a_0
  - krb5=1.17.1=hfafb76e_3
  - ld_impl_linux-64=2.34=h53a641e_7
  - libcurl=7.71.1=hcdd3856_5
  - libedit=3.1.20191231=he28a2e2_2
  - libev=4.33=h516909a_1
  - libffi=3.2.1=he1b5a44_1007
  - libgcc-ng=9.3.0=h24d8f2e_16
  - libgfortran-ng=7.5.0=hdf63c60_16
  - libgomp=9.3.0=h24d8f2e_16
  - libiconv=1.16=h516909a_0
  - libnghttp2=1.41.0=h8cfc5f6_2
  - libssh2=1.9.0=hab1572f_5
  - libstdcxx-ng=9.3.0=hdf63c60_16
  - libtiff=4.1.0=h2733197_1
  - libuv=1.39.0=h516909a_0
  - libxml2=2.9.10=h68273f3_2
  - lz4-c=1.9.2=he1b5a44_3
  - ncurses=6.2=he1b5a44_1
  - openssl=1.1.1g=h516909a_1
  - pcre=8.44=he1b5a44_0
  - pip=20.2.3=py_0
  - python=3.8.5=h1103e12_7_cpython
  - python_abi=3.8=1_cp38
  - readline=8.0=he28a2e2_2
  - rhash=1.3.6=h14c3975_1001
  - setuptools=49.6.0=py38h32f6830_0
  - sqlite=3.33.0=h4cf870e_0
  - swig=4.0.2=he1b5a44_0
  - tk=8.6.10=hed695b0_0
  - wheel=0.35.1=pyh9f0ad1d_0
  - xz=5.2.5=h516909a_1
  - zlib=1.2.11=h516909a_1009
  - zstd=1.4.4=h6597ccf_3
prefix: /home/nathan/anaconda3/envs/compile

The results of make are:

/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -c test.cpp -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -c vehicles.cpp -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -o eval test.o vehicles.o -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `__gnu_cxx::__exchange_and_add_single(int*, int)':
test.cpp:(.text+0xa8): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.cpp:(.text+0x10d): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.cpp:(.text+0x158): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `main':
test.cpp:(.text+0x2d4): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `vehicle::~vehicle()':
test.cpp:(.text._ZN7vehicleD2Ev[_ZN7vehicleD5Ev]+0x2f): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o:test.cpp:(.text._ZN7vehicleD2Ev[_ZN7vehicleD5Ev]+0x5c): more undefined references to `__ubsan_handle_type_mismatch' follow
collect2: error: ld returned 1 exit status
makefile:8: recipe for target 'eval' failed
make: *** [eval] Error 1

EDIT: Re-running with the verbose linker

/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -c test.cpp -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -c vehicles.cpp -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++ -I. -I/home/nathan/anaconda3/include -L/home/nathan/anaconda3/lib -v -o eval test.o vehicles.o -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr
Reading specs from /home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/specs
COLLECT_GCC=/home/nathan/anaconda3/envs/compile/bin/x86_64-conda_cos6-linux-gnu-c++
COLLECT_LTO_WRAPPER=/home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/lto-wrapper
Target: x86_64-conda_cos6-linux-gnu
Configured with: /home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/.build/x86_64-conda_cos6-linux-gnu/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=x86_64-conda_cos6-linux-gnu --prefix=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/gcc_built --with-sysroot=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/gcc_built/x86_64-conda_cos6-linux-gnu/sysroot --enable-languages=c,c++,fortran,objc,obj-c++ --with-pkgversion='crosstool-NG 1.23.0.449-a04d0' --enable-__cxa_atexit --disable-libmudflap --enable-libgomp --disable-libssp --enable-libquadmath --enable-libquadmath-support --enable-libsanitizer --enable-libmpx --with-gmp=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/.build/x86_64-conda_cos6-linux-gnu/buildtools --with-mpfr=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/.build/x86_64-conda_cos6-linux-gnu/buildtools --with-mpc=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/.build/x86_64-conda_cos6-linux-gnu/buildtools --with-isl=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/.build/x86_64-conda_cos6-linux-gnu/buildtools --enable-lto --enable-threads=posix --enable-target-optspace --enable-plugin --enable-gold --disable-nls --disable-multilib --with-local-prefix=/home/rdonnelly/mc/conda-bld/compilers_linux-64_1534865402226/work/gcc_built/x86_64-conda_cos6-linux-gnu/sysroot --enable-long-long --enable-default-pie
Thread model: posix
gcc version 7.3.0 (crosstool-NG 1.23.0.449-a04d0) 
COMPILER_PATH=/home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/:/home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/:/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/
LIBRARY_PATH=/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/:/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/:/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/lib/../lib/:/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/lib/../lib/:/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/../lib/:/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/lib/:/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/lib/:/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/
COLLECT_GCC_OPTIONS='-I' '.' '-I' '/home/nathan/anaconda3/include' '-L/home/nathan/anaconda3/lib' '-v' '-o' 'eval' '-fsanitize=address' '-fsanitize=undefined' '-fno-sanitize=vptr' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/collect2 -plugin /home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/liblto_plugin.so -plugin-opt=/home/nathan/anaconda3/envs/compile/bin/../libexec/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccaD6hAv.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o eval /home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/../lib/Scrt1.o /home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/../lib/crti.o /home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/crtbeginS.o -L/home/nathan/anaconda3/lib -L/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0 -L/home/nathan/anaconda3/envs/compile/bin/../lib/gcc -L/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/lib/../lib -L/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/lib/../lib -L/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/../lib -L/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/lib -L/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/lib -L/home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib -rpath /home/nathan/anaconda3/envs/compile/lib /home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/lib/../lib/libasan_preinit.o -lasan test.o vehicles.o -lstdc++ -lm -lubsan -lgcc_s -lgcc -lc -lgcc_s -lgcc /home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/crtendS.o /home/nathan/anaconda3/envs/compile/bin/../x86_64-conda_cos6-linux-gnu/sysroot/usr/lib/../lib/crtn.o
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `__gnu_cxx::__exchange_and_add_single(int*, int)':
test.cpp:(.text+0xa8): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.cpp:(.text+0x10d): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.cpp:(.text+0x158): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `main':
test.cpp:(.text+0x2d4): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o: in function `vehicle::~vehicle()':
test.cpp:(.text._ZN7vehicleD2Ev[_ZN7vehicleD5Ev]+0x2f): undefined reference to `__ubsan_handle_type_mismatch'
/home/nathan/anaconda3/envs/compile/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: test.o:test.cpp:(.text._ZN7vehicleD2Ev[_ZN7vehicleD5Ev]+0x5c): more undefined references to `__ubsan_handle_type_mismatch' follow
collect2: error: ld returned 1 exit status
makefile:8: recipe for target 'eval' failed
make: *** [eval] Error 1
NateM
  • 177
  • 1
  • 12
  • Run the linker verbose. – Christopher Yeleighton Sep 14 '20 at 16:27
  • @ChristopherYeleighton I've updated with the verbose linker output – NateM Sep 14 '20 at 16:37
  • The MAKEFILE shows `INCS` and `LIBS` pointing to the **base** env's folders, but the MAKE output shows you are working in the **compile** env. This may not be the issue, but it still should be fixed, i.e., `INCS` and `LIBS` should point to the `envs/compile/include` and `envs/compile/lib` directories. – merv Sep 14 '20 at 16:37
  • Well, that is not verbose enough. I can see -lubsan but the linker does not report where exactly it has found the library. – Christopher Yeleighton Sep 14 '20 at 16:43
  • @merv This does seem to be part ( or maybe even the entire ) problem. If I change the paths of (`INCS`) and (`LIBS`) to (`envs/compile/include`) and (`envs/compile/lib`) it can't find the libraries at all. I can't find the conda package that does install (`lasan`) and (`lubsan`) though. Do you know which ones do that? – NateM Sep 14 '20 at 16:53
  • Actually, what happens when you don't manipulate the `INCS` or `LIBS` paths? Some of the `cxx-compilers` subpackages include scripts to automatically manipulate compiler and linker flags. Perhaps you are inadvertently wiping out those settings? Also, did you use the full paths (e.g., `/home/nathan/anaconda3/envs/compile/include`) - I only gave relative paths to save typing. – merv Sep 14 '20 at 17:00
  • The other common issue is channel mixing. Make sure all your packages are (as much as possible) from a single channel (either **anaconda** or **conda-forge**). Missing references in shared objects is a typical symptom of this because different channels use different build stacks. – merv Sep 14 '20 at 17:03
  • 1
    @merv That did it! Leaving out `INCS` and `LIBS` showed that -lasan and -lubsan were not found. I also went through the environment and found a fair amount of library mixing. Changing everything to conda-forge allowed for a successful compile. If you want to submit an answer basically saying to not include the `anaconda3/include` and `anaconda3/lib` directories and to ensure all compiler libraries come from the same source I'll mark it as the answer. Thanks again! – NateM Sep 14 '20 at 17:29

1 Answers1

0

There could be a few possible issues.

Channel Mixing

Missing references in shared objects is a typical symptom of mixing package builds that come from different channels. This is because different channels use different build stacks and so symbols may have different names in shared objects compiled under those stacks.

Try to source as many of the packages you use from a single channel. Since most people often need at least one package that is only on conda-forge, the most generic solution is to give conda-forge priority when creating the environment, i.e., try

channels:
  - conda-forge
  - defaults

in the YAML (note anaconda is a subset of defaults, so it isn't needed).

Inconsistent Flags

Currently, the INCS and LIBS environment variables are set to point to the base environment. This could also lead to a channel mixing issue, since base is often dominated by package builds from defaults channel.

Instead, it would make more sense for those variables to point to the compile environment.

INCS = -I. -I/home/nathan/anaconda3/envs/compile/include
LIBS = -L/home/nathan/anaconda3/envs/compile/lib

Overwriting Environment Flags

The Conda build stacks that come from installing metapackages like cxx-compiler include packages with activation scripts that automatically manipulate the compiler and linker environment variables. For example, check under anaconda3/envs/compile/etc/conda/activate.d/. That is, the environment may already have a default configuration that correctly configures the paths to headers and runtime dependencies when activated.

It is possible that those are getting overwritten or interfered with by setting INCS and/or LIBS, so it might be sufficient to completely omit such manual specifications.

merv
  • 67,214
  • 13
  • 180
  • 245