Why does clang MemorySanitizer produce error in fstream open? - c++

I am trying to integrate Memory Sanitizer into my project. And following code raise an use-of-uninitialized-value error:
#include <fstream>
int main () {
std::ifstream ifs;
ifs.open ("test.txt", std::ifstream::in);
char c = ifs.get(); // this line doesn't matter
if (!ifs.good()) {
return -1;
}
ifs.close();
return 0;
}
$ clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O3 main.cpp -lstdc++
$ ./a.out
==43028==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55986e5d76ae in std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/fstream
#1 0x55986e5d76ae in main /home/promanjuk/learn/sanityzers/main.cpp:5:7
#2 0x7f6389ffdd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#3 0x7f6389ffde3f in __libc_start_main csu/../csu/libc-start.c:392:3
#4 0x55986e551334 in _start (/home/promanjuk/learn/sanityzers/a.out+0x21334) (BuildId: 597886c0634c006622192d0fa4c5ab7f169b7625)
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/fstream in std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode)
Exiting
$ clang --version
Ubuntu clang version 14.0.0-1ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
GodBolt behavior is the same (from clang 5.0 to 15.0, older versions produce a linker error).
Any ideas?
Thanks.
Code example I take from https://cplusplus.com/reference/fstream/ifstream/open/
So, this I've tried to run with/without
char c = ifs.get();
Tried different version of the clang.

Related

Why the packaged task is terminating after throwing system error? [duplicate]

I got a strange core dump which I copied from a part of code in http://en.cppreference.com/w/cpp/thread/packaged_task,
#include <future>
#include <iostream>
#include <cmath>
void task_lambda() {
std::packaged_task<int(int,int)> task([](int a, int b) {
return std::pow(a, b);
});
std::future<int> result = task.get_future();
task(2, 9);
std::cout << "task_lambda:\t" << result.get() << '\n';
}
int main() {
task_lambda();
}
I got this
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
[1] 28373 abort (core dumped) ./a.out
The call stack is like below:
#0 0x00007ffff71a2428 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff71a402a in __GI_abort () at abort.c:89
#2 0x00007ffff7ae484d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7ae26b6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7ae2701 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7ae2919 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7b0b7fe in std::__throw_system_error(int) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x0000000000404961 in std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (__once=..., __f=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x1246d>)
at /usr/include/c++/5/mutex:746
#8 0x0000000000403eb2 in std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) (
this=0x61ec30, __res=..., __ignore_failure=false) at /usr/include/c++/5/future:387
#9 0x0000000000402b76 in std::__future_base::_Task_state<task_lambda()::<lambda(int, int)>, std::allocator<int>, int(int, int)>::_M_run(<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>, <unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) (this=0x61ec30, __args#0=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>,
__args#1=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) at /usr/include/c++/5/future:1403
#10 0x00000000004051c1 in std::packaged_task<int (int, int)>::operator()(int, int) (this=0x7fffffffdca0, __args#0=2, __args#1=9) at /usr/include/c++/5/future:1547
#11 0x0000000000401c7d in task_lambda () at aa.cc:12
#12 0x0000000000401d1b in main () at aa.cc:19
Then I added some sample code into my program, it became
#include <iostream>
#include <cmath>
#include <future>
#include <thread>
int f(int x, int y) { return std::pow(x,y); }
void task_thread() {
std::packaged_task<int(int,int)> task(f);
std::future<int> result = task.get_future();
std::thread task_td(std::move(task), 2, 10);
task_td.join();
std::cout << "task_thread:\t" << result.get() << '\n';
}
void task_lambda() {
std::packaged_task<int(int,int)> task([](int a, int b) {
return std::pow(a, b);
});
std::future<int> result = task.get_future();
task(2, 9);
std::cout << "task_lambda:\t" << result.get() << '\n';
}
int main() {
task_lambda();
}
the error was gone. How can I correct the program by adding a function even though I never call it?
gcc version
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
Promgram compiled with command:
g++ -std=c++11 aa.cc -lpthread
With #fedepad's help, I got correct output by replace lpthread with pthread. But I still confused how second code work by add a dummy function!
I tried your first code snippet using the following version of g++:
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
and compiled with the following
g++ -o test_threads test_threads.cpp -std=c++11 -pthread
and I can run the program with no problems, and getting the following output:
$ ./test_threads
task_lambda: 512
If I then use the -lpthread as you did with the following
g++ -o test_threads test_threads.cpp -std=c++11 -lpthread
I get
$ ./test_threads
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
[1] 7890 abort ./test_threads
So please use -pthread as a flag and not -lpthread.
This behavior is also mentioned in the following
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830
There's a difference between -pthread and -lpthread.
Looking at the man page for g++
-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.
To have a look to what flags are activated for both one can check with the following:
g++ -dumpspecs | grep pthread
g++ -dumpspecs | grep lpthread
As one can clearly see, there are some preprocessor macros that are not activated if one is using -lpthread.

Did libstdc++'s layout for make_shared change between gcc 4.x and gcc 6.x?

Consider the following minimal example, consisting of three files:
foo.h:
#pragma once
#include <memory>
struct X {
uint64_t i = 0xdeadbeefdeadbeefULL;
};
void foo();
foo.cxx:
#include "foo.h"
void foo() {
std::make_shared<X>();
}
main.cxx:
#include <memory>
#include "foo.h"
template std::shared_ptr<X> std::make_shared();
int main() {
foo();
}
And then compile the two translation units with different versions of gcc:
$ g++-4.8.2 -g -std=c++11 -O0 -c foo.cxx -o foo.o
$ g++-6.2.0 -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -O0 -g main.cxx foo.o -fsanitize=address -fno-omit-frame-pointer
Note that I'm specifically compiling with the old ABI.
Running the resulting executable dies (it would not if both TUs were compiled with the same version of gcc):
==33535==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff8 at pc 0x000000401dcf bp 0x7fffffffd7f0 sp 0x7fffffffd7e8
WRITE of size 8 at 0x60300000eff8 thread T0
#0 0x401dce in X::X() (.../a.out+0x401dce)
#1 0x402758 in _ZN9__gnu_cxx13new_allocatorI1XE9constructIS1_IEEEvPT_DpOT0_ /.../gcc-4.8.2/include/c++/4.8.2/ext/new_allocator.h:120
#2 0x402721 in _ZNSt16allocator_traitsISaI1XEE12_S_constructIS0_IEEENSt9enable_ifIXsrNS2_18__construct_helperIT_IDpT0_EEE5valueEvE4typeERS1_PS6_DpOS7_ /.../gcc-4.8.2/include/c++/4.8.2/bits/alloc_traits.h:254
#3 0x4026fc in _ZNSt16allocator_traitsISaI1XEE9constructIS0_IEEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS1_PT_DpOS4_ /.../gcc-4.8.2/include/c++/4.8.2/bits/alloc_traits.h:393
#4 0x4026a6 in std::_Sp_counted_ptr_inplace<X, std::allocator<X>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<>(std::allocator<X>) /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr_base.h:399
#5 0x4025d4 in _ZN9__gnu_cxx13new_allocatorISt23_Sp_counted_ptr_inplaceI1XSaIS2_ELNS_12_Lock_policyE2EEE9constructIS5_IKS3_EEEvPT_DpOT0_ /.../gcc-4.8.2/include/c++/4.8.2/ext/new_allocator.h:120
#6 0x402572 in _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI1XSaIS1_ELN9__gnu_cxx12_Lock_policyE2EEEE12_S_constructIS5_IKS2_EEENSt9enable_ifIXsrNS7_18__construct_helperIT_IDpT0_EEE5valueEvE4typeERS6_PSC_DpOSD_ /.../gcc-4.8.2/include/c++/4.8.2/bits/alloc_traits.h:254
#7 0x40253a in _ZNSt16allocator_traitsISaISt23_Sp_counted_ptr_inplaceI1XSaIS1_ELN9__gnu_cxx12_Lock_policyE2EEEE9constructIS5_IKS2_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS6_PT_DpOSA_ /.../gcc-4.8.2/include/c++/4.8.2/bits/alloc_traits.h:393
#8 0x40249b in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<X, std::allocator<X>>(std::_Sp_make_shared_tag, X*, std::allocator<X> const&) /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr_base.h:502
#9 0x4023b1 in std::__shared_ptr<X, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<X>>(std::_Sp_make_shared_tag, std::allocator<X> const&) /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr_base.h:957
#10 0x402375 in std::shared_ptr<X>::shared_ptr<std::allocator<X>>(std::_Sp_make_shared_tag, std::allocator<X> const&) /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr.h:316
#11 0x4022c4 in std::shared_ptr<X> std::allocate_shared<X, std::allocator<X>>(std::allocator<X> const&) /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr.h:598
#12 0x402241 in _ZSt11make_sharedI1XIEESt10shared_ptrIT_EDpOT0_ /.../gcc-4.8.2/include/c++/4.8.2/bits/shared_ptr.h:614
#13 0x4021cf in foo() /.../foo.cxx:4
#14 0x400fd0 in main /.../main.cxx:7
#15 0x7ffff6208b34 in __libc_start_main (/lib64/libc.so.6+0x21b34)
#16 0x400ef8 (/.../a.out+0x400ef8)
This is true for gcc 7 and gcc 8 as well, but not true for gcc 5.4. This is specific to std::make_shared. What is going on here? I can't find any information about an ABI break, nor do I understand what kind of change could break this example.
C++11 support in GCC 4.8 was still experimental, so two objects compiled with -std=c++11 can only be linked together if they are both compiled by GCC 4.8.x
See https://stackoverflow.com/a/49119902/981959 for a more complete explanation.

C++: Core dump with packaged_task

I got a strange core dump which I copied from a part of code in http://en.cppreference.com/w/cpp/thread/packaged_task,
#include <future>
#include <iostream>
#include <cmath>
void task_lambda() {
std::packaged_task<int(int,int)> task([](int a, int b) {
return std::pow(a, b);
});
std::future<int> result = task.get_future();
task(2, 9);
std::cout << "task_lambda:\t" << result.get() << '\n';
}
int main() {
task_lambda();
}
I got this
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
[1] 28373 abort (core dumped) ./a.out
The call stack is like below:
#0 0x00007ffff71a2428 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff71a402a in __GI_abort () at abort.c:89
#2 0x00007ffff7ae484d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7ae26b6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7ae2701 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7ae2919 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7b0b7fe in std::__throw_system_error(int) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x0000000000404961 in std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (__once=..., __f=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x1246d>)
at /usr/include/c++/5/mutex:746
#8 0x0000000000403eb2 in std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) (
this=0x61ec30, __res=..., __ignore_failure=false) at /usr/include/c++/5/future:387
#9 0x0000000000402b76 in std::__future_base::_Task_state<task_lambda()::<lambda(int, int)>, std::allocator<int>, int(int, int)>::_M_run(<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>, <unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) (this=0x61ec30, __args#0=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>,
__args#1=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) at /usr/include/c++/5/future:1403
#10 0x00000000004051c1 in std::packaged_task<int (int, int)>::operator()(int, int) (this=0x7fffffffdca0, __args#0=2, __args#1=9) at /usr/include/c++/5/future:1547
#11 0x0000000000401c7d in task_lambda () at aa.cc:12
#12 0x0000000000401d1b in main () at aa.cc:19
Then I added some sample code into my program, it became
#include <iostream>
#include <cmath>
#include <future>
#include <thread>
int f(int x, int y) { return std::pow(x,y); }
void task_thread() {
std::packaged_task<int(int,int)> task(f);
std::future<int> result = task.get_future();
std::thread task_td(std::move(task), 2, 10);
task_td.join();
std::cout << "task_thread:\t" << result.get() << '\n';
}
void task_lambda() {
std::packaged_task<int(int,int)> task([](int a, int b) {
return std::pow(a, b);
});
std::future<int> result = task.get_future();
task(2, 9);
std::cout << "task_lambda:\t" << result.get() << '\n';
}
int main() {
task_lambda();
}
the error was gone. How can I correct the program by adding a function even though I never call it?
gcc version
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
Promgram compiled with command:
g++ -std=c++11 aa.cc -lpthread
With #fedepad's help, I got correct output by replace lpthread with pthread. But I still confused how second code work by add a dummy function!
I tried your first code snippet using the following version of g++:
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
and compiled with the following
g++ -o test_threads test_threads.cpp -std=c++11 -pthread
and I can run the program with no problems, and getting the following output:
$ ./test_threads
task_lambda: 512
If I then use the -lpthread as you did with the following
g++ -o test_threads test_threads.cpp -std=c++11 -lpthread
I get
$ ./test_threads
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
[1] 7890 abort ./test_threads
So please use -pthread as a flag and not -lpthread.
This behavior is also mentioned in the following
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830
There's a difference between -pthread and -lpthread.
Looking at the man page for g++
-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.
To have a look to what flags are activated for both one can check with the following:
g++ -dumpspecs | grep pthread
g++ -dumpspecs | grep lpthread
As one can clearly see, there are some preprocessor macros that are not activated if one is using -lpthread.

Gcc thread sanitizer false positive only for debug info flag

I am having a problem with Gcc's thread sanitizer that I cannot find on their bugzilla or on stackoverflow so I am unsure if I am missing something or if this really is a bug. If I create a main.cpp file containing:
#include <thread>
int main(){
std::thread t([](){});
t.join();
return 0;}
Now if I compile it using:
g++-4.9.2 -std=c++1y -fsanitize=thread -fPIE -pie -o TestProgram main.cpp
Running the resulting executable does not yield any problem. Yet if I add the debug info flag:
g++-4.9.2 -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp
then the thread sanitizer detects a data race:
WARNING: ThreadSanitizer: data race (pid=22683)
Write of size 8 at 0x7d0c0000efd8 by thread T1:
#0 operator delete(void*) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:592 (libtsan.so.0+0x000000049490)
#1 deallocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 (TestProgram+0x000000002089)
#2 deallocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:383 (TestProgram+0x000000001f78)
#3 _M_destroy /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:535 (TestProgram+0x0000000026f4)
#4 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:166 (libstdc++.so.6+0x0000000b5c51)
#5 ~__shared_count /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:666 (libstdc++.so.6+0x0000000b5c51)
#6 ~__shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:914 (libstdc++.so.6+0x0000000b5c51)
#7 ~shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr.h:93 (libstdc++.so.6+0x0000000b5c51)
#8 execute_native_thread_routine ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:95 (libstdc++.so.6+0x0000000b5c51)
Previous atomic write of size 4 at 0x7d0c0000efd8 by main thread:
#0 __tsan_atomic32_fetch_add ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interface_atomic.cc:468 (libtsan.so.0+0x0000000206ce)
#1 __exchange_and_add /usr/local/include/c++/4.9.2/ext/atomicity.h:49 (TestProgram+0x0000000014a0)
#2 __exchange_and_add_dispatch /usr/local/include/c++/4.9.2/ext/atomicity.h:82 (TestProgram+0x000000001557)
#3 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:146 (TestProgram+0x000000002ceb)
#4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:666 (TestProgram+0x000000002cb6)
#5 std::__shared_ptr<std::thread::_Impl_base, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:914 (TestProgram+0x000000002bc1)
#6 std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr.h:93 (TestProgram+0x000000002bed)
#7 thread<main()::<lambda()> > /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016f1)
#8 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
Location is heap block of size 48 at 0x7d0c0000efd0 allocated by main thread:
#0 operator new(unsigned long) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:560 (libtsan.so.0+0x0000000496d2)
#1 allocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:104 (TestProgram+0x000000001fe9)
#2 allocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:357 (TestProgram+0x000000001ecd)
#3 __shared_count<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:616 (TestProgram+0x000000001d99)
#4 __shared_ptr<std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:1090 (TestProgram+0x000000001ccb)
#5 shared_ptr<std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:316 (TestProgram+0x000000001c5f)
#6 allocate_shared<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:588 (TestProgram+0x000000001bf0)
#7 make_shared<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:604 (TestProgram+0x000000001ab0)
#8 _M_make_routine<std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/thread:193 (TestProgram+0x000000001919)
#9 thread<main()::<lambda()> > /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016bf)
#10 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
Thread T1 (tid=22685, running) created by main thread at:
#0 pthread_create ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:877 (libtsan.so.0+0x000000047c03)
#1 __gthread_create /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu/bits/gthr-default.h:662 (libstdc++.so.6+0x0000000b5d00)
#2 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:142 (libstdc++.so.6+0x0000000b5d00)
#3 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
SUMMARY: ThreadSanitizer: data race /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 deallocate
==================
ThreadSanitizer: reported 1 warnings
Now the exact same code compiled with clang++ (version 3.6.0 (trunk 221144)) does not detect a data race:
clang++ -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp
I am a bit quizzical about this behavior from gcc as:
1) passing an empty lambda function as an argument to a thread seems licit to me
2) gcc's behavior depends on the -g flag which doesn't strike me as having much to do with the thread sanitizer
3) under similar circumstances clang adopts a behavior that I would consider correct
Many thanks,
You mean this bug? It was reported for 4.8, but a similar report exists for 4.9.2.

unable to create a C++ ruby extension

I have problems creating a ruby extension to export a C++ library I wrote to ruby under OSX. This simple example:
#include <boost/regex.hpp>
extern "C" void Init_bayeux()
{
boost::regex expression("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
}
results in a bad_cast exception being thrown:
#0 0x00000001014663bd in __cxa_throw ()
#1 0x00000001014cf6b2 in __cxa_bad_cast ()
#2 0x00000001014986f9 in std::use_facet<std::collate<char> > ()
#3 0x0000000101135a4f in boost::re_detail::cpp_regex_traits_base<char>::imbue (this=0x7fff5fbfe4d0, l=#0x7fff5fbfe520) at cpp_regex_traits.hpp:218
#4 0x0000000101138d42 in cpp_regex_traits_base (this=0x7fff5fbfe4d0, l=#0x7fff5fbfe520) at cpp_regex_traits.hpp:173
#5 0x000000010113eda6 in boost::re_detail::create_cpp_regex_traits<char> (l=#0x7fff5fbfe520) at cpp_regex_traits.hpp:859
#6 0x0000000101149bee in cpp_regex_traits (this=0x101600200) at cpp_regex_traits.hpp:880
#7 0x0000000101142758 in regex_traits (this=0x101600200) at regex_traits.hpp:75
#8 0x000000010113d68c in regex_traits_wrapper (this=0x101600200) at regex_traits.hpp:169
#9 0x000000010113bae1 in regex_data (this=0x101600060) at basic_regex.hpp:166
#10 0x000000010113981e in basic_regex_implementation (this=0x101600060) at basic_regex.hpp:202
#11 0x0000000101136e1a in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign (this=0x7fff5fbfe710, p1=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100540b19 "", f=0) at basic_regex.hpp:652
#12 0x0000000100540a66 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign (this=0x7fff5fbfe710, p1=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100540b19 "", f=0) at basic_regex.hpp:379
#13 0x0000000100540a13 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign (this=0x7fff5fbfe710, p=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", f=0) at basic_regex.hpp:364
#14 0x000000010054096e in basic_regex (this=0x7fff5fbfe710, p=0x100540ae0 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", f=0) at basic_regex.hpp:333
#15 0x00000001005407e2 in Init_bayeux () at bayeux.cpp:10
#16 0x0000000100004593 in dln_load (file=0x1008bc000 "/Users/todi/sioux/lib/debug/rack/bayeux.bundle") at dln.c:1293
I compile the extension with:
g++ ./source/rack/bayeux.cpp -o /Users/todi/sioux/obj/debug/rack/bayeux.o -Wall -pedantic -Wno-parentheses -Wno-sign-compare -fno-common -c -pipe -I/Users/todi/sioux/source -ggdb -O0
And finally link the dynamic library with:
g++ -o /Users/todi/sioux/lib/debug/rack/bayeux.bundle -bundle -ggdb /Users/todi/sioux/obj/debug/rack/bayeux.o -L/Users/todi/sioux/lib/debug -lrack -lboost_regex-mt-d -lruby
I've searched the web and tried all kind of link and compiler switches. If I build a executable there is no such problem. Does someone else had such a problem and found a solution?
I've further investigated this and found that the function causing the exception looks like this:
std::locale loc = std::locale("C");
std::use_facet< std::collate<char> >( loc );
In the source of std::collate<> I found the throw statment:
use_facet(const locale& __loc)
{
const size_t __i = _Facet::id._M_id();
const locale::facet** __facets = __loc._M_impl->_M_facets;
if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
__throw_bad_cast();
#ifdef __GXX_RTTI
return dynamic_cast<const _Facet&>(*__facets[__i]);
#else
return static_cast<const _Facet&>(*__facets[__i]);
#endif
}
Does this makes any sense to you?
Update: I've tried Jan's suggestion:
Todis-MacBook-Pro:rack todi$ g++ -shared -fpic -o bayeux.bundle bayeux.cpp
Todis-MacBook-Pro:rack todi$ ruby -I. -rbayeux -e 'puts :ok'
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abort trap
versions:
Todis-MacBook-Pro:rack todi$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
Todis-MacBook-Pro:rack todi$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin10/4.5.2/lto-wrapper
Target: x86_64-apple-darwin10
Configured with: ../gcc-4.5.2/configure --prefix=/opt/local --build=x86_64-apple-darwin10 --enable-languages=c,c++,objc,obj-c++,fortran,java --libdir=/opt/local/lib/gcc45 --includedir=/opt/local/include/gcc45 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.5 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.5 --with-gxx-include-dir=/opt/local/include/gcc45/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --enable-stage1-checking --disable-multilib --enable-fully-dynamic-string
Thread model: posix
gcc version 4.5.2 (GCC)
Update:
It's not the bound-check in use_facet() that throws, but the next line, that actually does a dynamic cast. This example boils it down to maybe something with RTTI:
#define private public
#include <locale>
#include <iostream>
#include <typeinfo>
extern "C" void Init_bayeux()
{
std::locale loc = std::locale("C");
printf( "size: %i\n", loc._M_impl->_M_facets_size );
printf( "id: %i\n", std::collate< char >::id._M_id() );
const std::locale::facet& fac = *loc._M_impl->_M_facets[ std::collate< char >::id._M_id() ];
printf( "name: %s\n", typeid( fac ).name());
printf( "name: %s\n", typeid( std::collate<char> ).name());
const std::type_info& a = typeid( fac );
const std::type_info& b = typeid( std::collate<char> );
printf( "equal: %i\n", !a.before( b ) && !b.before( a ) );
dynamic_cast< const std::collate< char >& >( fac );
}
I've used printf() because usage of cout also fails. The output of the code above is:
size: 28
id: 5
name: St7collateIcE
name: St7collateIcE
equal: 1
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abort trap
Build with:
g++ -shared -fpic -o bayeux.bundle bayeux.cpp && ruby -I. -rbayeux -e 'puts :ok'
Update:
If I rename Init_bayeux to main() and link it to an executable, the output is the same, but no call to terminate.
Update:
When I write a little program to load the shared library and to execute Init_bayeux(), again, no exception is thrown:
#include <dlfcn.h>
int main()
{
void* handle = dlopen("bayeux.bundle", RTLD_LAZY|RTLD_GLOBAL );
void(*f)(void) = (void(*)(void)) dlsym( handle, "Init_bayeux" ) ;
f();
}
So it looks to me, that it might be a problem with how the ruby.exe was build. Does that make sense?
Update:
I had a look at the addresses containing the names of the two type_info objects. Same content, but different addresses. I added the -flat_namespace switch to the link command. Now the dynamic_cast works. The original Problem with the boost regex library still exists, but I think this might be solvable by linking boost statically into the shared library or by rebuilding the boost libraries with the -flat_namespace switch.
Update:
Now I'm back to the very first example with the boost regex expression, build with this command:
g++ -shared -flat_namespace -fPIC -o bayeux.bundle /Users/todi/boost_1_49_0/stage/lib/libboost_regex.a bayeux.cpp
But when loading the extension into the ruby interpreter, initializing of static symbols fails:
ruby(59384,0x7fff712b8cc0) malloc: *** error for object 0x7fff70b19500: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal SIGABRT, Aborted.
0x00007fff8a6ab0b6 in __kill ()
(gdb) bt
#0 0x00007fff8a6ab0b6 in __kill ()
#1 0x00007fff8a74b9f6 in abort ()
#2 0x00007fff8a663195 in free ()
#3 0x0000000100541023 in boost::re_detail::cpp_regex_traits_char_layer<char>::init (this=0x10060be50) at basic_string.h:237
#4 0x0000000100543904 in boost::object_cache<boost::re_detail::cpp_regex_traits_base<char>, boost::re_detail::cpp_regex_traits_implementation<char> >::do_get (k=#0x7fff5fbfddd0) at cpp_regex_traits.hpp:366
#5 0x000000010056005b in create_cpp_regex_traits<char> (l=<value temporarily unavailable, due to optimizations>) at pending/object_cache.hpp:69
#6 0x0000000100544c33 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign (this=0x7fff5fbfe090, p1=0x100567158 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", p2=0x100567191 "", f=0) at cpp_regex_traits.hpp:880
#7 0x0000000100566280 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign ()
#8 0x000000010056622d in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign ()
#9 0x0000000100566188 in boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::basic_regex ()
#10 0x0000000100566025 in Init_bayeux ()
#11 0x0000000100003a23 in dln_load (file=0x10201a000 "/Users/todi/sioux/source/rack/bayeux.bundle") at dln.c:1293
#12 0x000000010016569d in vm_pop_frame [inlined] () at /Users/todi/.rvm/src/ruby-1.9.2-p320/vm_insnhelper.c:1465
#13 0x000000010016569d in rb_vm_call_cfunc (recv=4303980440, func=0x100042520 <load_ext>, arg=4303803000, blockptr=0x1, filename=<value temporarily unavailable, due to optimizations>, filepath=<value temporarily unavailable, due to optimizations>) at vm.c:1467
#14 0x0000000100043382 in rb_require_safe (fname=4303904640, safe=0) at load.c:602
#15 0x000000010017cbf3 in vm_call_cfunc [inlined] () at /Users/todi/.rvm/src/ruby-1.9.2-p320/vm_insnhelper.c:402
#16 0x000000010017cbf3 in vm_call_method (th=0x1003016b0, cfp=0x1004ffef8, num=1, blockptr=0x1, flag=8, id=<value temporarily unavailable, due to optimizations>, me=0x10182cfa0, recv=4303980440) at vm_insnhelper.c:528
...
Again, this doesn't fail, when I load the shared library by the little c program from above.
Update:
Now I link the first example static:
g++ -shared -fPIC -flat_namespace -nodefaultlibs -o bayeux.bundle -static -lstdc++ -lpthread -lgcc_eh -lboost_regex-mt bayeux.cpp
With the same error:
ruby(15197,0x7fff708aecc0) malloc: *** error for object 0x7fff7027e500: pointer being freed was not allocated
otool -L confirmed that every library is linked static:
bayeux.bundle:
bayeux.bundle (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
debug:
If I link against the boost debug version, then it works like expected.
For the records: I've now build boost and my application with the very same compiler (version 4.2.1 [official apple version]). No problems so far. Why it will not work as expected when the ruby extension links all libraries statically is a miracle to me. Thank to all who put time into this issue.
Kind regards
Torsten