Asan dynamic runtime is missing on Ubuntu 18+ - c++

If I compile a simple program (sample.cpp):
#include <cstdio>
int main() {
printf("Hello, World");
return 0;
}
with a shared sanitizer library, i.e.
clang++-12 -fsanitize=address -shared-libsan sample.cpp -o sample
I am getting the following error when running ./sample:
./sample: error while loading shared libraries: libclang_rt.asan-x86_64.so: cannot open shared object file: No such file or directory
I am getting this error for the sample code on my local machine (Ubuntu 20.04 and clang-12), as well as our build runner (Ubuntu 18.04 and clang-10).
Am I missing something, or shall I submit a bug and to whom? (The options I see are Ubuntu or LLVM/Clang teams)
Please note that this question is distinct from the one that was suggested as duplicate in close votes (this was confirmed by the linked question author in comments).

This is a deficiency of the clang front-end -- when given -shared-libsan flag, it should automatically add -Wl,-rpath=/usr/lib/llvm-NN/lib/clang/MM.M.M/lib/linux to the link line, but it doesn't.
You could do that yourself by using e.g.
CXX=clang++-12
$CXX -fsanitize=address -shared-libsan sample.cpp -o sample \
-Wl,-rpath=$(dirname $($CXX --print-file-name libclang_rt.asan-x86_64.so))

Related

Clang compiler couldn't find C/C++ standard libraries when I gave a specific target although it works without giving target

I am currently using clang11 on ubuntu to compile any c/c++ code and it works fine but when I tried to compile any code (including any standard library) to assembly code for any specific target like x86_64 (even I have x86_64) riscv with giving a flag that --target=x86_64 or --target=riscv32 I got errors for any standard library that I included in my code. A simple example:
// ex.cpp
#include<iostream>
int main(){
int a = 5;
int b = 3;
std::cout << a - b;
}
Without giving flag for a spesific target works fine:
clang++-11 -S ex.cpp -o ex.s
With --target=riscv32 flag:
clang++-11 --target=riscv32 -S ex.cpp -o ex.s
gives this error:
ex.cpp:1:9: fatal error: 'iostream' file not found
also without standard libraries gives no error even I give a spesific target.
I am searching for a solution for days but I couldn't find any proper solution for this problem, most of them says try to include gnu libraries and subfolders like -I/usr/include/x86_64-linux-gnu/c++/ but it doesn't work for me.
Please don't say use g++ compiler, for adding an optimization I need clang.
Actually I am trying to compile my codes for riscv target, linking with g++ and running with spike (doesn't differ --target=... or -target ...):
clang++-11 -target riscv32-unknown-elf -march=rv32gc -fno-addrsig -S ex.cpp -o ex.s
~/riscv/bin/riscv32-unknown-elf-g++ ex.s -o ex
~/riscv/riscv-isa-sim/build/spike --isa=RV32GC ~/riscv/riscv-pk/build/pk ex
And it works fine without include a standard library.
Now, I want to ask that
Can I solve this problem simply?
or
Can I use clang directly from riscv bin utils like ~/riscv/bin/riscv32-unknown-elf-clang++ (I saw something like this on the net but couldn't find) adding and building a submodule to my riscv directory?
Edit: As #NateEldredge said, for x86_64 target triple should --target=x86_64-linux-gnu but for riscv as a target triple riscv32-unknown-elf I still have the same errors. Is there a proper target flag for riscv any other than --target=riscv32-unknown-elf? Maybe I am missing that point.
I solved my problem by linking compilations with riscv-gnu-toolchain built and also answered a similar question here in detailed: Using Clang to compile for RISC-V
Simply we need cross-compilation.
Further information you can also look here: https://github.com/lowRISC/riscv-llvm#how-can-i-build-upstream-llvmclang-and-use-it-to-cross-compile-for-a-riscv32-target

lli: LLVM ERROR: Cannot select: X86ISD::WrapperRIP TargetGlobalTLSAddress:i64

Running the following code with clang++ -S -emit-llvm main.cpp && lli main.ll on Linux(Debian)
#include <future>
int main () {
return std::async([]{return 1;}).get();
}
fails to run on lli due to the following error:
LLVM ERROR: Cannot select: 0xd012e0:
i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i8** #_ZSt15__once_callable> 0 [TF=10]
0xd020c0: i64 = TargetGlobalTLSAddress<i8** #_ZSt15__once_callable> 0 [TF=10]
In function: _ZSt9call_onceIMNSt13__future_base13_State_baseV2EFvPSt8functionIFSt10unique_ptrINS0_12_Result_baseENS4_8_DeleterEEvEEPbEJPS1_S9_SA_EEvRSt9once_flagOT_DpOT0_
Questions:
What does it mean?
Are there any compiler-flags that fix this problem?
using -stdlib=libc++ compiles and runs successfully*; what specific features is libstdc++ using that cause this issue ?
EDIT:
The motivation behind this question is to understand the differences between libc++ and libstdc++ that leads to this specific error message (on Linux) in llvm's orcjit.
On OSX gcc has been deprecated and clang uses by default libc++.
To reproduce this error on OSX you probably have to install gcc & use -stdlib=libstdc++.
Here is the llvm-ir (it's unfortunately to big to embed it here directly)
EDIT:
The error turned out to be caused by the lack of TLS support in the JITer. This answer describes another problem concerned with linking and lli.
If you have a look at the generated IR from clang++ -std=c++11 -S -emit-llvm test.cpp, you will find that many of the symbols, e.g. _ZNSt6futureIiE3getEv, are only declared, but never defined. The linker is never called, since -S "Only run[s] preprocess and compilation steps" (clang --help).
lli only executes the IR Module and does no "implicit" linking, how is it supposed to know which libraries to link in?
There are different solutions to this, depending on why you are using lli:
compile and link the IR Module: llc main.cpp && clang++ -lpthread main.s (pthread is required s. What is the correct link options to use std::thread in GCC under linux?)
(unconfirmed) use LD_PRELOAD="x.so y.so" to force-load the libraries before running lli
JIT the module programmatically and use LoadLibraryPermanently(nullptr) (adds symbols of the program into the search space) and LoadLibraryPermanently(file, err) for additional libs (s. http://llvm.org/docs/doxygen/html/classllvm_1_1sys_1_1DynamicLibrary.html)
I can only guess as to why libc++ works for you since it fails on my machine, but presumably it's the case because it is loaded into lli already and lli calls sys::DynamicLibrary::LoadLibraryPermanently(nullptr) to add the program's symbols to its JIT search space (s. https://github.com/llvm-mirror/llvm/blob/release_40/tools/lli/OrcLazyJIT.cpp#L110).
The LLVM-dev mailinglist pointed out:
What does it mean?
The llvm-backend in orcjit does currently not support thread-local storage(TLS)
a minimal example is:
extern thread_local int tls;
int main() {
tls = 42;
return 0;
}
using -stdlib=libc++ compiles and runs successfully*; what specific features is libstdc++ using that cause this issue ?
this works because libc++ future::get implementation does not use thread_local keyword.
Are there any compiler-flags that fix this problem?
currently there is no solution.
Using lli -relocation-model=pic trades this problem with a relocation failure.

Custom GCC 4.8.2 on RHEL6 gives build error with std::shared_ptr

I am using CMake 2.8.11 and GCC 4.8.2. I was building some C++ code which used std::shared_ptr which built fine in MS VS 2012 but when I tried the same on RHEL6 using GCC 4.8.2, I promptly ran into the following error:
error: 'shared_ptr' is not a member of 'std'
I found this question with responses that I thought addressed and I promptly added -std=c++11 to my CMAKE_CXX_FLAGS, but I still keep running into the error. I add the flag in CMake simply using:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE STRING "Add C++ 11 flags")
I set my custom compiler in CMake using:
SET(GCC_DIR "</path/to/custom>/gcc")
SET(CMAKE_CXX_COMPILER "${GCC_DIR}/bin/g++ CACHE FILEPATH "CXX compiler")
SET(CMAKE_C_COMPILER "${GCC_DIR}/bin/gcc CACHE FILEPATH "C compiler")
The include is
#include <memory>
which in turn has
#include <bits/shared_ptr.h>
which defines the shared_ptr class. So I'm not sure why I keep getting the error (and yes I cleared cached and rebuilt after adding the -std=c++11 compiler option). Any ideas are very much appreciated.
EDIT 1:
I created a simple program (main.cpp) as follows:
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<int> pint = std::make_shared<int>();
std::cout << "Pint points to " << pint.get() << "\n";
return 0;
}
Then I built it using <path/to/custom/>g++ main.cpp -o prog and promptly ran into the same error (above). Next I did: <path/to/custom/>g++ -std=c++11 main.cpp -o prog and it compiles & runs OK. For my real application, I added the -std=c++11 flag to linker flags as well (in addition to compiler flags) in my CMake config system, but I still see the same error. Proceeding to check the CMakeCache to see if the flags are property registered, but any ideas are appreciated.
EDIT 2:
Suprisingly, I found in CMakeCache that the -std=c++11 flag is not being added to the CMAKE_CXX_FLAGS, etc. So this must have to do with the error. I am trying to fix it so that it actually takes this flag. Thanks all.
The answer confirms the hunch in EDIT 2 of my question. Apparently CMake 2.8.x is not appending to the variable CMAKE_CXX_FLAGS using the SET command using the syntax shown in my question (as per the documentation); I tried other variants of the SET command to append, to no avail.
So finally, instead of appending, I assigned separately for the case when C++11 is to be enabled and when it is to be disabled, as follows:
IF(USE_C++11)
...
ELSE(USE_C++11)
...
ENDIF(USE_C++11)
This worked fine. Thanks to #nos for the idea to make an isolated example.

Exec Format Error Eclipse CDT

I have a basic C++ program in Eclipse CDT:
#include <iostream>
using namespace std;
int main()
{
std::cout << "Hello World!";
}
However, when I try to build it, I get an Exec Format Error. Here is the output produced by the compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o hey.o "..\\hey.cpp"
g++: error: spawn: Exec format error
I am using MinGW Toolchain. I am on 64-bit Windows, and I think that may have something to do with it. Would anyone know how to get this program running?
Edit
Running the exact command in command prompt in the directory where my source file is works just fine, without throwing errors, but it still doesn't work in Eclipse
So, I have fixed this myself by installing the 64-bit version of MinGW (http://sourceforge.net/projects/mingw-w64/). It now compiles and builds noramlly

Libc++ linked programs fail with symbol lookup error

I've recently built libc++ from scratch as my prject needs some features that are not yet implemnted in libstdc++.
I try to compile the hello world program located in src/main.cpp with line
clang -Wall -stdlib=libc++ -std=c++11 -c src/main.cpp -obuild/main.o
and the build suceeds
Then I link it with
clang -lc++ build/main.o -o qasix
and the linking suceeds too.
But when I run the program with
./qasix
I get the following error:
./qasix: symbol lookup error: /usr/local/lib/libc++.so.1: undefined symbol: _ZTVN10__cxxabiv120__si_class_type_infoE
I would like to know why this is occurring and also how to fix it.
I am on Xubuntu 13.10 if that's of any help.
PS: This problem popped up yesterday. Earlier other libc++ programs would compile fine.
This started when I did a debug build of a program with the -g flag and it compiled and ran fine, but all later programs complained about this symbol lookup failure. Please help.
it appears that you need the support library "libc++abi". It provides things like low-level exception support, type_info support, etc.
For Ubuntu (as opposed to Xubuntu), it appears that you can get it here: http://www.ubuntuupdates.org/package/core/saucy/universe/base/libc++abi-dev