I'm experiencing some very weird problems with static boost libraries (Boost 1.45.0-2 from MacPorts, compiled as fat/universal (x86/x86_64) libraries) under Mac OS X 10.6.6 with GCC 4.5.
The error message is
main(78485) malloc: *** error for object 0x1000e0b20: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
[1] 78485 abort (core dumped)
and a tiny bit of example code which will trigger this problem:
#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem.hpp>
#include <iostream>
int main (int argc, char **argv) {
std::cout << boost::filesystem::current_path ().string () << '\n';
}
This problem always occurs when linking the static boost libraries into the binary. Linking dynamically will work fine, though.
Even more information:
gcc versions tested/used: Apple GCC 4.2.1 (works/runs), MacPorts GCC 4.5.2 (fails)
flags tested/used: none, -fPIC, -fPIC -g, -fPIC -g -ggdb3 -gdwarf-2 -O0
gdb output with MP GCC 4.5.2/any flags of the above:
(gdb) run
Starting program: /Users/ionic/crashtest/bin/ctest Reading symbols for shared libraries .++++++++++++++++++++++.................................................................................................................. done
ctest(80366) malloc: *** error for object 0x100fe6b20: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal SIGABRT, Aborted. 0x00007fff81a4e616 in __kill ()
(gdb) bt full
#0 0x00007fff81a4e616 in __kill () No symbol table info available.
#1 0x00007fff81aeecca in abort () No symbol table info available.
#2 0x00007fff81a066f5 in free () No symbol table info available.
#3 0x0000000100f763e9 in std::string::_M_mutate () No symbol table info available.
#4 0x0000000100f7644c in std::string::_M_replace_safe () No symbol table info available.
#5 0x0000000100f77edd in std::string::replace () No symbol table info available.
#6 0x000000010000713d in std::string::_M_rep () at /usr/include/c++/4.2.1/bits/basic_string.h:1412
to = (string &) Cannot access memory at address 0x0
Seems like it's working fine with Apple's (quite old) GCC version, but failing badly with the new GCC build by MacPorts.
otool -L ctest:
./../../bin/ctest:
/opt/local/lib/gcc45/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.14.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
/opt/local/lib/gcc45/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
I've seen various reports for quite a similar OS X bug with GCC 4.2 and the _GLIBCXX_DEBUG macro set, but this one seems even more generic, as I'm neither using XCode, nor setting the macro (even undefining it does not help. I tried it just to make sure it's really not related to this problem.) Doesn't seem to be related at all to this problem, as the same code is working fine with Apple's GCC.
As Apple's GCC doesn't include any C++0x features yet, I'd indeed like to use the currently stable GCC version.
Does anybody have any pointers to why this is happening or even maybe a solution (rather than using the dynamic library workaround)?
Best regards,
Mihai
The problem was that Boost has been built using Apple's GCC 4.2.1, whilst I've been building the project using a different compiler.
As I tried to link the static Boost libraries, also the GCC 4.2.1 libstdc++ was put into the binary.
However, at the same time the other GCC version was linking in its libstdc++ and name space problems were inherent, thus the wrong functions were called and the like.
The most simple fix is re-building Boost with your target GCC version and retry the building of your program (ofc. using the self-built Boost.)
Be warned: do not try to change the compiler MacPorts uses for building Boost (it's even not easily possible), or system breakage may occur. Instead, build Boost on your own.
Related
I'm trying to make a multi-threaded program but am having a weird problem with thread local vectors. Here's the (stripped-down to only have the error) code:
#include <vector>
#include <iostream>
thread_local std::vector<int> vec;
int main(){
vec.push_back(3);
std::cout << vec[0];
// Make you push enter to show the error is at the end
std::cin.ignore();
}
The program compiles fine and runs mostly fine, but after I press enter I get a "program has stopped working" message. I ran it in gdb and got this error:
Program received signal SIGSEGV, Segmentation fault.
0x004030b0 in std::vector<int, std::allocator<int> >::~vector() ()
Somehow, there's an error in the vector's destructor. Going through it with a breakpoint shows that this error happens as the program is quitting.
Making the vector not thread local makes the program work, but of course I need it to be thread local. If I don't interact with the vector at all, the program works fine.
I'm thinking I'll have to use some alternative, but does anybody know a way to make this work? Thanks!
EDIT: I'm stupid and forgot more info on my system. I'm using Windows Vista 64-bit. Running g++ -v gives me:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=C:/MinGW/bin/../libexec/gcc/i686-w64-mingw32/5.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with [edited out because it's too big and probably not relevant]
Thread model: posix
gcc version 5.2.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)
The thread model might actually have a lot to do with it.
It is setup dependent; I have successfully compiled and run your example program on Windows 7 (64 bit) with the 64 bit MinGW. Perhaps it is related to the fact that you use the 32 bit MinGW installation on 64 bit platform? My g++ -v gives the following (same version and thread model as yours, different arch):
Using built-in specs.
COLLECT_GCC=g++
Target: x86_64-w64-mingw32
Thread model: posix
gcc version 5.2.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
I'm compiling the Crypto++ library at -O3. According to Undefined Behavior Sanitizer (UBsan) and Address Sanitizer (Asan), its OK. The program runs fine at -O2 (and -O3 on many platforms).
Its also OK according to Valgrind under -O2. At -O3, Valgrind dies with "Your program just tried to execute an instruction that Valgrind does not understand". I'm fairly certain that's because of SSE4 instructions and vectorizations at -O3.
However, I'm catching a crash on some platforms with -O3. This particular machine is Fedora 22 i686, and its has GCC 5.2.1. The frame in question shows this=0xfffffffc:
Program received signal SIGSEGV, Segmentation fault.
0x0807be29 in CryptoPP::DL_GroupParameters_IntegerBased::GetEncodedElementSize
(this=0xfffffffc, reversible=0x1) at gfpcrypt.h:55
55 unsigned int GetEncodedElementSize(bool reversible) const {return GetModulus().ByteCount();}
The best I can tell, there's nothing located around that address:
(gdb) info shared
From To Syms Read Shared Object Library
0xb7fdd860 0xb7ff6b30 Yes (*) /lib/ld-linux.so.2
0xb7eb63d0 0xb7f7a344 Yes (*) /lib/libstdc++.so.6
0xb7e005f0 0xb7e32bd8 Yes (*) /lib/libm.so.6
0xb7951060 0xb7980cc4 Yes (*) /lib/libubsan.so.0
0xb7932090 0xb7948001 Yes (*) /lib/libgcc_s.so.1
0xb7916840 0xb79238d1 Yes (*) /lib/libpthread.so.0
0xb775d3f0 0xb78a0b6b Yes (*) /lib/libc.so.6
0xb7741a90 0xb7742a31 Yes (*) /lib/libdl.so.2
I've seen this=0x00000000 if a static class object declared in one translation unit is used in another translation unit before initialization is complete. But I don't recall seeing 0xfffffffc in the past.
What are some potential reasons for this=0xfffffffc? Or how can I troubleshoot it further?
If you have a 32 bits machine 0xfffffffc is ((int*)nullptr)-1. So perhaps you are taking the previous element of a nil pointer (e.g. wrongly using some reverse iterator, etc etc...)
Use the bt or backtrace command of gdb to understand what has happened. I guess that the trouble is in the caller (or its caller, etc...)
Try also some other compiler (e.g. some older version of GCC and several versions of Clang/LLVM....). You could have some undefined behavior that your other tools did not detect as such. You need to understand if the bug is inside Crypto++ (or perhaps, but very unlikely, it is inside GCC itself; then report a bug on GCC bugzilla....). If you suspect the compiler, pass -S -fverbose-asm -fdump-tree-all -O3 to g++ to understand what GCC is doing.... (this will dump hundreds of files, including the generated .s assembler code).
Ask also on crypto++ lists; perhaps report the bug on Crypto++ bug tracker. Test with other versions or snapshot of that library
BTW, I'm not sure that -fsanitize=undefined or -fsanitize=address should be used with -O3; I guess that they are more suitable with -O0 -g or -Og -g
The issue is somewhat similar to this question but the accepted answer does not really propose a solution or workaround.
In our project, we have a dylib and the main executalble. The dylib is compiled with -fno-rtti, while the executable does use RTTI. The problem happens when an exception (e.g. std::bad_alloc) is thrown from the dylib and is caught in the exe.
(Before you yell "exceptions need RTTI so you must have it on!", please note that the RTTI necessary for exceptions is always generated regardless of the -frtti or -fno-rtti setting. This is actually documented in the -fno-rtti flag description. The issue on OS X is that it's not generated in the same way)
After some investigation, the following was discovered:
In the dylib (-fno-rtti), there is a local copy of the exception's RTTI structures; in particular, the __ZTISt9bad_alloc symbol (typeinfo for std::bad_alloc).
The exe (-frtti) imports the typeinfo symbol from libstdc++.6.dylib and does not have a local copy
Since the exception handling code relies on comparing typeinfo pointers to determine exception match, the matching fails, and only the catch(...) succeeds.
So far I see the following options:
1) compile everything, or at least the files that throw and catch exceptions, with -frtti. This is doable but I don't like the idea of generating RTTI for everything even if we don't use it; and the list of files which work with exceptions is prone to get stale.
2) when linking the dylib, somehow make the linker throw away the weak exception definition from the object file and use the one from libstdc++.6.dylib. So far I was not successful.
3) ???
I made a small test illustrating the problem.
--- throw.cpp ---
#include <iostream>
#if defined(__GNUC__)
#define EXPORT __attribute__((visibility("default")))
#else
#define EXPORT __declspec(dllexport)
#endif
EXPORT void dothrow ()
{
std::cout << "before throw" << std::endl;
throw std::bad_alloc();
}
--- main.cpp ---
#include <stdio.h>
#include <iostream>
#if defined(__GNUC__)
#define IMPORT extern
#else
#define IMPORT __declspec(dllimport)
#endif
IMPORT void dothrow ();
int main (void) {
try {
std::cout << "trying lib->main exception" << std::endl;
dothrow ();
}
catch ( const std::bad_alloc& )
{
std::cout << "caught bad_alloc in main - good." << std::endl;
}
catch (...)
{
std::cout << "caught ... in main - bad!" << std::endl;
}
}
--- makefile ---
# for main exe
CFLAGS_RTTI=-m32 -frtti -fvisibility=hidden -fvisibility-inlines-hidden -shared-libgcc -funwind-tables
# for dylib
CFLAGS_NORTTI=-m32 -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -shared-libgcc
# for linking; some switches which don't help
CLFLAGS=-Wl,-why_live,-warn_commons,-weak_reference_mismatches,error,-commons,error
all: test
test: libThrow.dylib main.o
g++ $(CFLAGS_RTTI) -o test main.o -lthrow -L./ $(CLFLAGS)
main.o: main.cpp
g++ $(CFLAGS_RTTI) -c -o main.o main.cpp
throw.o: throw.cpp
g++ $(CFLAGS_NORTTI) -c -o throw.o throw.cpp
libThrow.dylib: throw.o
g++ $(CFLAGS_NORTTI) -dynamiclib -o libThrow.dylib throw.o
clean:
rm test main.o throw.o
Running:
$ ./test
trying lib->main exception
before throw
caught ... in main - bad!
Symbols of the files involved:
$ nm -m throw.o | grep bad_alloc
000001be (__TEXT,__textcoal_nt) weak private external __ZNSt9bad_allocC1Ev
000001be (__TEXT,__textcoal_nt) weak private external __ZNSt9bad_allocC1Ev
00000300 (__TEXT,__eh_frame) weak private external __ZNSt9bad_allocC1Ev.eh
(undefined) external __ZNSt9bad_allocD1Ev
00000290 (__DATA,__const_coal) weak external __ZTISt9bad_alloc
000002a4 (__TEXT,__const_coal) weak external __ZTSSt9bad_alloc
(undefined) external __ZTVSt9bad_alloc
$ nm -m libThrow.dylib | grep bad_alloc
00000ce6 (__TEXT,__text) non-external __ZNSt9bad_allocC1Ev
(undefined) external __ZNSt9bad_allocD1Ev (from libstdc++)
00001050 (__DATA,__const) weak external __ZTISt9bad_alloc
00000e05 (__TEXT,__const) weak external __ZTSSt9bad_alloc
(undefined) external __ZTVSt9bad_alloc (from libstdc++)
$ nm -m main.o | grep bad_alloc
(undefined) external __ZTISt9bad_alloc
$ nm -m test | grep bad_alloc
(undefined) external __ZTISt9bad_alloc (from libstdc++)
Note: similar compilation options on Linux and Windows works fine. I can throw exceptions from a shared object/dll and catch them in the main exe, even if they're compiled with different -frtti/-fno-rtti options.
EDIT: here's how I ended up solving it for the specific case of bad_alloc:
#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
#define throw_nomem std::__throw_bad_alloc
#else
#define throw_nomem throw std::bad_alloc
#endif
EXPORT void dothrow ()
{
std::cout << "before throw" << std::endl;
throw_nomem();
}
The function __throw_bad_alloc is imported from libstdc++.6.dylib and so always throws a correct type.
You can simply move all your "throw exceptions" infrastructure to the helper library with -frtti enabled - and link it to other stuff. Without actual code it's hard to tell, if this decomposition is possible or not.
Here is some sample code:
// Thrower.cc
void DoThrow() {
throw std::bad_alloc;
}
// LibraryNoRTTI.cc
void f() {
DoThrow();
}
// main.cc
int main() {
try {
f();
}
catch(std::bad_alloc&) {}
return 0;
}
The simplest way is to move all your throw invocations to the separate functions with appropriate types, like: throw std::logical_error("message"); goes to void ThrowLogicError(const std::string& message) { ... }
If there is a problem with encapsulation (private exception classes), then you may make friends with throwing functions.
If you still want to use (throw/catch) exceptions inside the non-rtti library, then you have to make separation between internal exceptions and exceptions used in your library API.
The good way is to use native C++ throw-catch for internal purposes - and then rethrow some exceptions, using rtti-based library functions, to the outside - according to your interface:
// Thrower.cc
void Rethrow(const std::exception& e) {
throw e;
}
// LibraryNoRTTI.cc
namespace {
void internal_stuff() {
throw std::logical_error("something goes wrong!");
}
} // namespace
// You even may explicitly specify the thrown exceptions in declaration:
void f() throw(std::logical_error) {
try {
internal_stuff();
}
catch(std::exception& e) {
Rethrow(std::logical_error(std::string("Internal error: ") + e.what());
}
}
Start Edit March 4, 2014
I think the Clang++ compiler has a better chance of obtaining the desired exception handling. I have found this Stack Overflow post: Clang and the default compiler in OS X Lion. The post has helpful script lines for modifying ~/.bashrc to change the system default compiler settings on Snow Leopard and how to use the LLVM GCC. For Clang, add inside the ~/.bashrc:
# Set Clang as the default compiler for the system
export CC=clang
export CFLAGS=-Qunused-arguments
export CPPFLAGS=-Qunused-arguments
If the c++ symbolic link is not present, either call clang++ directly or add the c++ link as desired (e.g.
ln -s /usr/bin/clang++ c++
). It is a good idea to check all symbolic links within the /usr/bin by running:
ls -l `which lynx` | more
On my Mavericks command line tools installation c++ points to clang++ and cc points to clang. The g++ compiler version says:
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx- include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
The clang++ complier version says:
$clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
Notice that the g++ include directory path is set to /usr/include/c++/4.2.1, probably not the include path needed to resolve the issue.
MacPorts: Hopefully the Answer for any OS X version
The best solution I can find to obtain any Clang++ compiler version for any OS X version is to use the open source tool called MacPorts. There is extensive documentation in the MacPorts Guide. The application is called port and can be installed from an OS X installation package or obtain the source code and compile locally. The following is from installing MacPorts onto Snow Leopard. The other OS X versions should be similar. After obtaining MacPorts for Snow Leopard, run the port search command to observe all the different clang related ports available. For example, it looks like this:
$port search clang
The partial list of search results from Snow Leopard 10.6.8 is:
clang-2.9 #2.9_13 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.0 #3.0_12 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.1 #3.1_7 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.2 #3.2_2 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.3 #3.3_2 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.4 #3.4 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.5 #3.5-r202097 (lang)
C, C++, Objective C and Objective C++ compiler
clang_select #0.1 (sysutils)
common files for selecting default clang version
Then I successfully installed clang-3.3 with: sudo port install clang-3.3. After this completes, see the available versions by typing port select --list clang. Then run the
sudo port select --set clang mp-clang-3.3
or similar. When I execute clang++ --version it says (as expected):
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin10.8.0
Thread model: posix
Same for when the clang --version command is executed (after closing and restarting the terminal):
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin10.8.0
Thread model: posix
There are MacPorts installation packages for many OS X versions (e.g. Leopard, Snow Leopard, Lion, Mountain Lion, Mavericks, etc.). I did not go any further back than Leopard with my search. If using an OS X older than Leopard, please review the MacPorts site thoroughly.
If curious about details on where to find Xcode 4.2 (or used to be able to obtain it), I have found this post regarding obtaining Xcode 4.2 for Snow Leopard Xcode 4.2 download for Snow Leopard. Then these two additional ones: Can i use the latest features of C++11 in XCode 4 or OSX Lion? [duplicate] and Can I use C++11 with Xcode?. After trying a couple links to see if the 4.2 Xcode remains available for Snow Leopard, no joy.
More than likely the MacPorts libc++ installation will be necessary to have full C++11 support. To install the more recent version, execute sudo port install libcxx. The contents of the /usr/lib will be overwritten with the current C++11 libraries (as necessary per MacPorts Ticket #42385: libcxx/libcxxabi: OS update can render system unusable
If libc++ still appears to be lacking, try this: "libc++" C++ Standard Library. Then use this:
$ export TRIPLE=-apple-
$ export MACOSX_DEPLOYMENT_TARGET=10.6
$ ./buildit
from How to build libc++ with LLVM/Clang 3.3 on Mac OS X 10.6 "Snow Leopard".
On OS X Lion, Mountain Lion, and Mavericks, they all have recent independent command line tools downloads on the Apple Developer site. The Clang version may be older than what one needs, so be sure to confirm which C++11 features are needed when using the Developer site command line tools' Clang.
End Edit March 4, 2014
The above macro detection may need to change from __GNUC__ to __clang__ or __clang_version__. It all depends on what the predefined compiler macros are for each OS X compiler, and the best way to detect as needed here. The Stack Overflow answer at: What predefined macro can I use to detect clang? should be helpful in configuring the command line to obtain them (e.g. clang++ -dM -E -x c /dev/null).
I have noticed when running the preceding example command that there is a predefined macro called __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__. On the Mavericks clang++, the macro value is 1090. It might be necessary to have a family of #ifdef logic to set the appropriate EXPORT macro for each OS X clang++ compiler.
Well, even though I have accepted an answer it did not solve all problems. So I'm writing down the solution which did work in the end.
I made a small tool for post-processing the object files and marking the local symbols as UNDEF. This forces the linker to use definitions from libstdc++ and not local ones from the file. The basic approach of the tool is:
load the Mach-O header
walk the load commands and find the LC_SYMTAB command
load the list of symbols (struct nlist) and the strings
walk the symbols and look for those that we need (e.g. __ZTISt9bad_alloc)
set the found symbols' type to N_UNDF|N_EXT.
after processing, write the modified symbol table back to the file.
(I also made a similar implementation for ELF)
I post-process any file that's using std exceptions, either for throwing or for catching. To make sure the file list does not go stale, I added a post-link check for unwanted local symbols using nm.
This seems to resolve all the problems I've had so far.
I have downloaded and installed the jsoncpp library. I then try to use the library in my own application:
#include <json/json.h>
void parseJson() {
Json::Reader reader;
}
int main(int argc, char ** argv) {
parseJson();
exit(0);
}
The program compiles and links fine, but it crashes with SIGSEGV when running. The gdb backtrace looks like this:
(gdb) bt
#0 0x0000003a560b7672 in __gnu_cxx::__exchange_and_add () from /usr/lib64/libstdc++.so.6
#1 0x00000000004031e9 in std::string::_Rep::_M_dispose (this=0xffffffffffffffe9, __a=#0x7fffbfe60e57)
at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:232
#2 0x0000000000403236 in ~basic_string (this=0x7fffbfe60fb0)
at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:478
#3 0x00000000004038d4 in ~Reader (this=0x7fffbfe60eb0) at /private/joaho/Parser/opm-parser/external/json/json-cpp/include/json/reader.h:23
#4 0x0000000000402990 in parseJson () at /private/joaho/Parser/opm-parser/opm/parser/eclipse/ExternalTests/ExternalTests.cpp:51
#5 0x00000000004029ab in main (argc=1, argv=0x7fffbfe610c8)
at /home/user/Parser/opm-parser/opm/parser/eclipse/ExternalTests/ExternalTests.cpp:56
I.e. to me it seems to crash in the destructor. As far as I can tell the Json::Reader does not have it's own dstructor, so this must be a default destructor. As you can see I am running a quite old version of g++ - could that be the problem?
As I commented:
When compiled with GCC version 4.8.1 on Debian/Sid (so libjsoncpp-dev 0.6.0~rc2-3) as g++-4.8 -g -Wall -I/usr/include/jsoncpp/ esjson.cc -ljsoncpp -o esjson your program is compiled without warnings, and does not crash when running.
And GCC 4.1.2 is really old (febr. 2007 !) and is not supported anymore, and not very well C++ standard conforming (GCC, now at version 4.8.1, has made huge progress on C++ standard conformance since 4.1).
So I am not sure GCC 4.1. is faulty, but I won't be surprised it is: it had bad C++ reputation, and both the C++ standard and the GCC compiler have been improved a lot since that. Upgrading your GCC is worth the effort, both for better support of C++ and for improved diagnostics and optimizations.
So I suggest you to use a newer GCC; if you don't have root access, consider compiling its from its source tarball; build it outside of the source tree with e.g. ../gcc-4.8.1/configure --program-suffix=-4.8 --prefix=$HOME/pub then make then make install - after having installed its dependencies
I am pretty new to Ubuntu, but I can't seem to get this to work. It works fine on my school computers and I don't know what I am not doing. I have checked usr/include and time.h is there just fine. Here is the code:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
timespec time1, time2;
int temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
//do stuff here
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
return 0;
}
I am using CodeBlocks as my IDE to build and run as well. Any help would be great, thank you.
Add -lrt to the end of g++ command line. This links in the librt.so "Real Time" shared library.
example:
c++ -Wall filefork.cpp -lrt -O2
For gcc version 4.6.1, -lrt must be after filefork.cpp otherwise you get a link error.
Some older gcc version doesn't care about the position.
Since glibc version 2.17, the library linking -lrt is no longer required.
The clock_* are now part of the main C library. You can see the change history of glibc 2.17 where this change was done explains the reason for this change:
+* The `clock_*' suite of functions (declared in <time.h>) is now available
+ directly in the main C library. Previously it was necessary to link with
+ -lrt to use these functions. This change has the effect that a
+ single-threaded program that uses a function such as `clock_gettime' (and
+ is not linked with -lrt) will no longer implicitly load the pthreads
+ library at runtime and so will not suffer the overheads associated with
+ multi-thread support in other code such as the C++ runtime library.
If you decide to upgrade glibc, then you can check the compatibility tracker of glibc if you are concerned whether there would be any issues using the newer glibc.
To check the glibc version installed on the system, run the command:
ldd --version
(Of course, if you are using old glibc (<2.17) then you will still need -lrt.)
I encountered the same error. My linker command did have the rt library included -lrt which is correct and it was working for a while. After re-installing Kubuntu it stopped working.
A separate forum thread suggested the -lrt needed to come after the project object files.
Moving the -lrt to the end of the command fixed this problem for me although I don't know the details of why.