I am trying to compile & link a simple C++ program using threads on an aarch64 based linux host. The simple program is as follows:
#include <iostream>
#include <thread>
#include <atomic>
using namespace std;
#define ITERATIONS 1000
// to be called for multi threaded execution
void increment_atomic_thread (atomic<int>& a)
{
for (int i = 0; i < ITERATIONS; i++)
{
a++;
}
}
int main (int argc, char* argv[])
{
atomic<int> a, b, c, d;
thread t1 ( [&]() { increment_atomic_thread(a); } );
thread t2 ( [&]() { increment_atomic_thread(b); } );
thread t3 ( [&]() { increment_atomic_thread(c); } );
thread t4 ( [&]() { increment_atomic_thread(d); } );
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
This code compile fine on an x86-64 machine, however I am getting an ld error in the aarch64 machine as follows (the output is last few lines when compiling with --verbose):
attempt to open /usr/lib/gcc/aarch64-linux-gnu/7/../../../aarch64-linux-gnu/crtn.o succeeded
/usr/lib/gcc/aarch64-linux-gnu/7/../../../aarch64-linux-gnu/crtn.o
libm.so.6 needed by /usr/lib/gcc/aarch64-linux-gnu/7/libstdc++.so
found libm.so at /usr/lib/gcc/aarch64-linux-gnu/7/../../../aarch64-linux-gnu/libm.so
/usr/bin/ld: /usr/lib/aarch64-linux-gnu/libpthread.a(pthread_create.o): relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `__stack_chk_guard##GLIBC_2.17' which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /usr/lib/aarch64-linux-gnu/libpthread.a(pthread_create.o)(.text+0x9cc): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `__stack_chk_guard##GLIBC_2.17'
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
The compile command is:
g++ -g -std=c++17 -lpthread -Xlinker --verbose -o pthread_basic.app pthread_basic.cpp /usr/lib/aarch64-linux-gnu/libpthread.a
Thanks #Some programmer dude. Pasting his comment here:
You don't need both -lpthread and /usr/lib/aarch64-linux-gnu/libpthread.a. Remove
the last and keep -lpthread but put it at the end of the command line (order matters for libraries).
Related
This question already has answers here:
Undefined reference to pthread_create in Linux
(16 answers)
Closed 3 years ago.
I'm using a class of threads with a header and cpp file.
When I put both of them and empty test file it writes:
g++ -g -pedantic -ansi -Wall -Werror -std=c++03 -I../include -c -o test.o test.cpp
g++ -g test.o thread.o -o test
thread.o: In function `Thread::~Thread()':
/home/tomer/work/mt/hash2/cpp/thread.cpp:15: undefined reference to `pthread_detach'
thread.o: In function `Thread::start()':
/home/tomer/work/mt/hash2/cpp/thread.cpp:40: undefined reference to `pthread_create'
thread.o: In function `Thread::join()':
/home/tomer/work/mt/hash2/cpp/thread.cpp:49: undefined reference to `pthread_join'
thread.o: In function `Thread::cancel()':
/home/tomer/work/mt/hash2/cpp/thread.cpp:58: undefined reference to `pthread_cancel'
thread.o: In function `Thread::detach()':
/home/tomer/work/mt/hash2/cpp/thread.cpp:66: undefined reference to `pthread_detach'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'test' failed
make: *** [test] Error 1
I just tried to comppile Thread.h and Thread.cpp
//Thread.h looks like this:
#ifndef THREAD_H
#define THREAD_H
#include <cstddef>
#include <pthread.h>
#include <string>
class Thread
{
public:
Thread(size_t a_userID = 0);
virtual ~Thread();
bool start();
void join();
void cancel();
void detach();
private:
static void* threadMainFunction(void *);
virtual void run() = 0;
bool isAlive(std::string a_msg);
private:
bool m_joinable;
protected:
pthread_t m_threadID;
size_t m_userID;
};
#endif
//Thread.cpp looks like this:
#include <exception>
#include "Thread.h"
#include <iostream>
Thread::Thread(size_t a_userID)
: m_joinable(true)
, m_threadID(0)
, m_userID(a_userID)
{
}
Thread::~Thread()
{
if(m_joinable)
{
pthread_detach(m_threadID);
}
}
void* Thread::threadMainFunction(void *a_thread)
{
Thread* thread = reinterpret_cast<Thread*>(a_thread);
try
{
thread->run();
}
catch(const std::exception& e)
{
std::cout<<"what exepction\n";
std::cerr << e.what() << '\n';
}
catch(...)
{
throw;
}
return 0;
}
bool Thread::start()
{
int r = pthread_create(&m_threadID, 0, threadMainFunction, this);
return r == 0;
}
void Thread::join()
{
if(isAlive("Thread::join on thread not started"))
{
void *status;
pthread_join(m_threadID, &status);
m_joinable = false;
}
}
void Thread::cancel()
{
if(isAlive("Thread::cancel on thread not started"))
{
pthread_cancel(m_threadID);
}
}
void Thread::detach()
{
if(isAlive("Thread::detach on thread not started"))
{
pthread_detach(m_threadID);
}
}
bool Thread::isAlive(std::string a_msg)
{
if(m_threadID == 0)
{
throw(std::runtime_error(a_msg));
return false;
}
return true;
}
The issue you are facing here is not a build issue, but a link issue. When building thread.o, the compiler knows pthread_create exists and is defined somewhere because declared in the pthread.h header.
If you used nm to look at the symbols used in thread.o, you would see something similar to this:
U _pthread_create
U _pthread_detach
...
This tells you that thread.o references multiple Undefined symbols including pthread_create. In other words, the machine code for pthread_create is unknown at this point. This is perfectly fine until you need to link your object files into an executable file, which is the role of the linker.
At this stage, you must tell the linker where to find these undefined symbols, perhaps from another object file or a static/shared library. For pthread, the symbols are defined in libpthread, which you can likely find in a system directory as libpthread.a. You can tell g++ to link this library by adding -lpthread (note that lib from libpthread is omitted when using -l):
g++ -g test.o thread.o -o test -lpthread
In general, if you use symbols referenced in a static library lib${LIBNAME}.a available in ${LIBDIR} directory, you can tell the linker to use it with:
g++ -g *.o -L$LIBDIR -l${LIBNAME}
this is my code:
#include <boost/thread.hpp>
#include <iostream>
using namespace boost;
void task1()
{std::cout << "This is task1!" << std::endl;}
void task2()
{std::cout << "This is task2!" << std::endl;}
int main ()
{
thread thread_1 = thread(task1);
thread thread_2 = thread(task2);
thread_2.join();
thread_1.join();
return 0;
}
and I compile with:
g++ test.cc -o test -lboost_thread -lpthread -lboost_system
compile failed:
/tmp/ccN9cPiI.o: In function `boost::system::generic_category()':test.cc(.text._ZN5boost6system16generic_categoryEv[_ZN5boost6system16generic_categoryEv]+0x7):
undefined reference to `boost::system::detail::generic_category_instance'
collect2: error: ld returned 1 exit status
What's wrong with that?
My system is Ubuntu 18.04,boost is 1_68.0.
I just tried your example and it works. I tried with boost_1_66_0 and boost_1_65_1 on Ubuntu.
The actual problem is boost itself, not your installation. You can check open bug here:
https://github.com/boostorg/system/issues/24
I have a problem while running an executable file with dlopen function used to open shared and sanitized library with a one simple function.
I use precompiled Clang 3.9.0 for Ubuntu 14.04.
My question is: Is it possible to run it properly, so I can look for undefined behavior errors in the library while running an executable ? If the answers is yes, then how ?
I have two files:
//simpledll.cpp
#include <cstdio>
int hehe(int argc) {
int k = 0x7fffffff;
k += argc;
return 0;
}
//dlopen.cpp
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main() {
void* handle;
handle = dlopen("simpledll.so", RTLD_LAZY);
if(!handle) {
fprintf(stderr, "%s\n", dlerror());
}
int (*function)(int) = reinterpret_cast<int (*)(int)> (dlsym(handle, "_Z4hehei"));
if (function == nullptr)
fprintf(stderr, "Nope\n");
else
function(1000); // this yields signed integer overflow
return 0;
}
I have tried to get it to work in two steps (both have failed)
Step I
Compile the executable with:
clang++ dlopen.cpp -ldl --std=c++11 -o dlopen
Compile the library with:
clang++ -fsanitize=undefined -shared -o simpledll.so -fPIC simpledll.cpp
Result:
./dlopen: symbol lookup error: simpledll.so: undefined symbol: __ubsan_handle_add_overflow
Step II (idea from this forum)
Compile the executable as in Step I,
Compile the library with:
clang++ -fsanitize=undefined -shared -Wl,--whole-archive -L/usr/local/lib/clang/3.9.0/lib/linux/ -lclang_rt.ubsan_standalone_cxx-x86_64 -Wl,--no-whole-archive -lclang_rt.ubsan_standalone-x86_64 -Wl,--no-whole-archive -o simpledll.so -fPIC simpledll.cpp
Result:
==11478==Sanitizer CHECK failed: /home/development/llvm/3.9.0/final/llvm.src/projects/compiler-rt/lib/ubsan/ubsan_init.cc:61 ((UBSAN_MODE_UNKNOWN)) != ((ubsan_mode)) (0, 0)
Note that in Step II, if we substitute the function in the shared library with the one that has no undefined behavior code, the program runs without a CHECK failed error. This indicates that UBSAN has found an undefined behavior code, however it was unable to report it properly.
Regards,
Jaszczur
I am currently using Boost 1.54.0. I am following the code from this example.
example_44_01.cpp
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <iostream>
void wait(int seconds)
{
boost::this_thread::sleep_for(boost::chrono::seconds{seconds});
}
void thread()
{
for (int i = 0; i < 5; ++i)
{
wait(1);
std::cout << i << std::endl;
}
}
int main(int argc, char** argv)
{
boost::thread t{thread};
t.join();
return 0;
}
So, it looks like all I need is the -lboost_thread, and -lboost_chrono libraries to link to at compile time. I also added the -lboost_system.
Here are my execution scripts.
g++-7 -Wall -std=c++1z -g -c example_44_01.cpp -o example_44_01.o
g++-7 -Wall -std=c++1z -g example_44_01.o -o example_44_01 -lboost_system -lboost_thread -lboost_chrono &>result.txt
What's going on here? This is the result.txt file:
example_44_01.o: In function `boost::this_thread::sleep_for(boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > const&)':
/usr/local/include/boost/thread/pthread/thread_data.hpp:243: undefined reference to `boost::this_thread::hidden::sleep_for(timespec const&)'
collect2: error: ld returned 1 exit status
I've compiled and linked other programs with the same libraries without error. So is the error in the code? This seems doubtful as the code is straight from the documentation. Any insight is appreciated.
I had this issue once because I was indeliberately using different versions of Boost (I had first installed Boost from commandline, then a few months later on, manually from zip).
Try adding the path to your Boost libraries to the compiler. For instance, if your libraries are stored at /usr/local/lib, try:
g++-7 -Wall -std=c++1z -g example_44_01.o -o example_44_01 -L/usr/local/lib -lboost_system -lboost_thread -lboost_chrono &>result.txt
I have some troubles trying to compile a program with multi-threading from the standard template library.
It return me a obscure error when i try to compile the following program :
#include <iostream>
#include <thread>
void foo()
{
std::cout << "Thread 1\n";
}
int main(int argc, char** argv)
{
std::thread tr(foo);
std::cout << "Main thread\n";
tr.join();
return 0;
}
I don't understand the error :
/tmp/ccE8EtL1.o : In the function « std::thread::thread<void (&)()>(void (&)()) » :
file.cpp:(.text._ZNSt6threadC2IRFvvEJEEEOT_DpOT0_[_ZNSt6threadC5IRFvvEJEEEOT_DpOT0_]+0x21) : undefined reference to « pthread_create »
collect2: error : ld has return 1 execution status code
I compile it with :
g++ -std=c++14 file.cpp -o test -Wall
Can anyone help me please ?
Pass -pthread to the compiler. This flag combines what is necessary to compile and link the pthread library (-lpthread is not always enough). See this question.