[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
--- Comment #8 from l_heldt at poczta dot onet dot pl 2006-10-31 11:12 --- There is a similar problem in _M_detach_all() function. It iterates through list of iterators without obtaining lock. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
--- Comment #13 from l_heldt at poczta dot onet dot pl 2006-10-31 13:12 --- (In reply to comment #12) About _M_detach_all specifically, it's called only by ~_Safe_sequence_base(), thus only when the container itself is destructed. Therefore, I don't think it may cause problems in practice. Unfortunatelly it may. Suppose there are two threads: consumer/producer where producer is creating container, taking iterator to the container and passing the container to consumer thread. Consumer thread is simply deallocating the container - thus calling _M_detach_all function. At the same time iterator destructor is called which causes SIGSEGV. We actually encountered this problem - this is not taken from code review only. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
--- Comment #15 from l_heldt at poczta dot onet dot pl 2006-10-31 13:42 --- (In reply to comment #14) (In reply to comment #13) We actually encountered this problem - this is not taken from code review only. Again, adding a mutex to that those *_base functions it's trivial. Now, please start preparing reduced testcases for such issues, because apprently you *know* how to do that. The approach No test case - no bug maybe can be considered naive as you say, on the other hand enforcing it eventually makes for sound software engineering, because would be even more naive to rely on submitter itself and no one else in the world to test a candidate fix, thus not being able to avoid regressions at a later stage within the project. I tried to prepare a simple testcase but without any success. It seems to be extremely hard to hit the moment when pointers are actually changed. Trivial programs do not reveal the problem. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
--- Comment #20 from l_heldt at poczta dot onet dot pl 2006-10-31 17:23 --- (In reply to comment #16) (In reply to comment #15) I tried to prepare a simple testcase but without any success. It seems to be extremely hard to hit the moment when pointers are actually changed. Trivial programs do not reveal the problem. Ok, but you should try harder, because often in the past we managed to prepare complete testcases for races and generally MT issues too, which seemed very tricky at the outset. I think we are totally misunderstood here. I don't have time to prepare complex test cases revealing problems not in my code. I have found the bug I even found the cause of the bug and it is still not enough for you. If you don't want to be informed about problems in stl then what is this bugzilla for? I have already made a workaround in my code to avoid the debug container in certain situations so it's not me who will actually benefit from the fix. I reported this issue to help other developers who might encounter similar problem. Because of version policies in my company probably I won't be even able to use your fix. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
--- Comment #7 from l_heldt at poczta dot onet dot pl 2006-10-19 13:51 --- (In reply to comment #2) Please attach a complete test case, not a sketch. -benjamin This bug is a pure race-condition. There is no test case which would reveal it with a 100% certainty. I have noticed the bug after receiving strange SIGSEGV in _M_invalidate() function. After reviewing the code I found the problem stated in this bug report. Of course you can say: No test case - no bug but I guess this would be a very naive approach. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug c++/29496] New: _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode
_M_invalidate function in safe_iterator.tcc is not thread safe against _M_detach()/_M_attach() functions from _Safe_iterator_base. Here is the example of erronous scenario: Thread1() { list::iterator iter; lock(mutex); iter = myList.begin(); // do something with iter unlock(); } Thread2() { lock(mutex); myList.erase(myList.begin()); unlock(); } The problem in this scenario is that while calling erase(), _M_invalidate() function is called which goes through the list of all iterators without taking a lock on __gnu_internal::iterator_base_mutex. At the same time another thread can be deallocating lists iterator - thus calling _M_detach() function. This leads to a SIGSEGV in _M_invalidate() function. You should either remove concurrency support from GLIBCXX_DEBUG mode or provide full support. -- Summary: _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l_heldt at poczta dot onet dot pl GCC host triplet: Linux 2.6.9-42.ELsmp #1 SMP http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29496
[Bug c++/27836] New: Compiler generates bad assembler code for xaddl __asm__ function
Compiler generates bad assembler code for xaddl __asm__ function when -O3 is turned on. Following code will generate bad assembly: #include iostream inline int atomicAddReturn(int i, int volatile* p) { int __i; __i = i; __asm__ __volatile__( lock;xaddl %0, %1 :=r(i) :m(*p), r(i)); return i + __i; } void f(int value) { std::cout value std::endl; } void func(volatile int * p) { for (int i = 0; i 10; ++i) { f(atomicAddReturn(1, p)); } std::cout Value == *p std::endl; } int main() { volatile int value = 0; func(value); return 0; } It generates wrong assembly near xaddl function: call_ZNSolsEm movl%eax, (%esp) call_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ addl$16, %esp decl%esi js .L44 .L28: movl$1, %edx #APP lock;xaddl %eax, (%ebx) #NO_APP movl_ZSt4cout, %ecx leal1(%eax), %edx movl-12(%ecx), %eax addl$_ZSt4cout, %eax movl12(%eax), %eax testb $64, %al jne .L21 testb $8, %al jne .L21 subl$8, %esp pushl %edx pushl $_ZSt4cout call_ZNSolsEl movl%eax, (%esp) call_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ addl$16, %esp decl%esi jns .L28 .L44: As you can see edx is set with value 1 instead of eax. After compilation and execution program prints random data. -- Summary: Compiler generates bad assembler code for xaddl __asm__ function Product: gcc Version: 3.4.5 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l_heldt at poczta dot onet dot pl http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27836
[Bug c++/27836] Compiler generates bad assembler code for xaddl __asm__ function
--- Comment #1 from l_heldt at poczta dot onet dot pl 2006-05-31 11:14 --- Problem does not show up in g++-4.0. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27836
[Bug c++/27836] Compiler generates bad assembler code for xaddl __asm__ function
--- Comment #3 from l_heldt at poczta dot onet dot pl 2006-05-31 11:43 --- Can you tell me how correct asm body should look like? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27836
[Bug c++/27045] New: c++ is generating incorrect optimized code for xor operations on long long
c++ is generating incorrect optimized code for xor operations on long long. Version which is affected is: g++ (GCC) 4.0.2 20051125 (Red Hat 4.0.2-8) Following (proper) code is inlined into bad assembly when optimization is turned on: namespace __gnu_cxx { /** hash specialization for uint64 */ template class hashuint64 { public: size_t operator()(uint64 const number) const { hashuint32 uint32Hasher; uint32 const *p = (uint32 *)number; return uint32Hasher(p[0]) ^ uint32Hasher(p[1]); } }; /** hash specialization for RequestId */ template class hashRequestId { public: size_t operator()(RequestId const requestId) const { hashuint64 uint64Hasher; return uint64Hasher(requestId.getV1()) ^ uint64Hasher(requestId.getV2()); } }; } Part of bad assembly: call_ZNK9RequestId5getV1Ev movl-20(%ebp), %ebx movl%esi, (%esp) movl%eax, -24(%ebp) movl-24(%ebp), %eax movl%edx, -20(%ebp) xorl%eax, %ebx call_ZNK9RequestId5getV2Ev movl-16(%ebp), %ecx movl%eax, -16(%ebp) movl-12(%ebp), %eax movl%edx, -12(%ebp) xorl%ecx, %eax and it probably should be something like: call_ZNK9RequestId5getV1Ev movl%eax, -24(%ebp) movl%edx, -20(%ebp) movl-20(%ebp), %ebx movl%esi, (%esp) movl-24(%ebp), %eax xorl%eax, %ebx call_ZNK9RequestId5getV2Ev movl%eax, -16(%ebp) movl%edx, -12(%ebp) movl-16(%ebp), %ecx movl-12(%ebp), %eax xorl%ecx, %eax It seems that compiler reads values from stack before setting them after call to getV1() or getV2(). Bug shows up only when optimization is turned on. I am attaching simple demo program which should run when optimization is set to 0 and crash when it is set to 2 or 3. -- Summary: c++ is generating incorrect optimized code for xor operations on long long Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l_heldt at poczta dot onet dot pl http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27045
[Bug c++/27045] c++ is generating incorrect optimized code for xor operations on long long
--- Comment #1 from l_heldt at poczta dot onet dot pl 2006-04-05 15:17 --- Created an attachment (id=11212) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11212action=view) File containing hash specifications -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27045
[Bug c++/27045] c++ is generating incorrect optimized code for xor operations on long long
--- Comment #2 from l_heldt at poczta dot onet dot pl 2006-04-05 15:17 --- Created an attachment (id=11213) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11213action=view) Implementation of RequestId -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27045
[Bug c++/27045] c++ is generating incorrect optimized code for xor operations on long long
--- Comment #3 from l_heldt at poczta dot onet dot pl 2006-04-05 15:18 --- After compilation: g++ test.cpp req.cpp -O0 program works fine. After compilation with: g++ test.cpp req.cpp -O2 it breaks with SIGABRT. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27045
[Bug libstdc++/24469] Possible race condition in mt_allocator causing SIGSEGV
--- Comment #4 from l_heldt at poczta dot onet dot pl 2005-11-15 12:26 --- Unfortunately I cannot perform such test because it would require changing stdlibc++ on many machines. My solution to this problem is setting GLIBCXX_FORCE_NEW variable before starting application. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24469
[Bug libstdc++/24469] New: Possible race condition in mt_allocator causing SIGSEGV
In function deallocate(pointer _p, size_type __n) there is no synchronization on __bin._M_used[__block-_M_thread_id] variable. During block deallocation current thread decrements other threads _M_used variable without a lock. This can result in undefined value of _M_used variable which than is used to calculate __remove size. SIGSEGV shows up in following code: while (__remove-- 0) __tmp = __tmp-_M_next; Since __remove variable might have undefined value code may surpass the end of the list. Increment and decrement operations are not atomic and should be placed in critical section to avoid such situation. Bug is very hard to reproduce. There must be many threads allocating memory and deallocating other threads memory. I have found this bug by code inspection - not gdb. -- Summary: Possible race condition in mt_allocator causing SIGSEGV Product: gcc Version: 3.4.2 Status: UNCONFIRMED Severity: critical Priority: P1 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l_heldt at poczta dot onet dot pl GCC host triplet: Linux 2.6.12 #4 SMP http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24469
[Bug libstdc++/19265] problem with _S_destroy_thread_key when using dynamic libraries
--- Additional Comments From l_heldt at poczta dot onet dot pl 2005-01-17 14:12 --- I cannot check proposed changes because of compilation problems. I have changed makefiles in libstdc++/src directory but I am getting errors while linking: /remote/beta4/lukasz/gcc2/gcc/g++ -shared-libgcc -B/remote/beta4/lukasz/gcc2/gcc/ -nostdinc++ -B/remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/bin/ -B/remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/lib/ -isystem /remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/include -isystem /remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/sys-include -g -O2 -D_GLIBCXX_ASSERT -ffunction-sections -fdata-sections -fmessage-length=0 -DLOCALEDIR=/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/po/share/locale -g -O2 -D_GNU_SOURCE -o abi_check abi_check.o -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src/.libs -lv3test -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite -lm -Wl,--rpath -Wl,/remote/beta4/lukasz/gcc2/gcc -Wl,--rpath -Wl,/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src/.libs /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb110deallocateEPSsj+0x74): In function `compare_symbols': /remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pooltrue::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPSsNS_20__common_pool_policyINS_6__poolELb110deallocateEPS1_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pooltrue::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb110deallocateEPS3_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pooltrue::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb18allocateEjPKv+0x73): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:269: undefined reference to `__gnu_cxx::__pooltrue::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb18allocateEjPKv+0x196): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_construct.h:107: undefined reference to `__gnu_cxx::__pooltrue::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPNS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb110deallocateEPS7_j+0x74): In function `compare_symbols': /remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pooltrue::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocINS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb110deallocateEPS6_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pooltrue::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb18allocateEjPKv+0x72): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator_base_types.h:165: undefined reference to `__gnu_cxx::__pooltrue::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb18allocateEjPKv+0x193): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator.h:623: undefined reference to `__gnu_cxx::__pooltrue::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t
[Bug libstdc++/19265] New: problem with _S_destroy_thread_key when using dynamic libraries
There is a problem with _S_destroy_thread_key when loading dynamic libraries. This function will be called when thread finishes. But unfortunatelly when using dynamic libraries the code might be removed from memory using dlclose(). After that thread that has been modifing stl containers inside dynamic library will finish with SEGV. Probably the best solution would be to make this method static and move it's body to shared library or enable manual thread detachment. -- Summary: problem with _S_destroy_thread_key when using dynamic libraries Product: gcc Version: 3.4.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: l_heldt at poczta dot onet dot pl CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19265
[Bug libstdc++/19265] problem with _S_destroy_thread_key when using dynamic libraries
--- Additional Comments From l_heldt at poczta dot onet dot pl 2005-01-05 15:54 --- I have used following scenario: 1. dlopen dynamic library 2. execute a method inside dynamic library which addes integer to vector 3. dlclose 4. try to exit cleanly Program crashes with SIGSEGV. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19265