[Bug libstdc++/29496] _M_invalidate function is not thread-safe in GLIBCXX_DEBUG mode

2006-10-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-10-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-10-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-10-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-10-19 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-10-18 Thread l_heldt at poczta dot onet dot pl
_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

2006-05-31 Thread l_heldt at poczta dot onet dot pl
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

2006-05-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-05-31 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-04-05 Thread l_heldt at poczta dot onet dot pl
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

2006-04-05 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-04-05 Thread l_heldt at poczta dot onet dot pl


--- 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

2006-04-05 Thread l_heldt at poczta dot onet dot pl


--- 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

2005-11-15 Thread l_heldt at poczta dot onet dot pl


--- 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

2005-10-21 Thread l_heldt at poczta dot onet dot pl
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

2005-01-17 Thread l_heldt at poczta dot onet dot pl

--- 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

2005-01-05 Thread l_heldt at poczta dot onet dot pl
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

2005-01-05 Thread l_heldt at poczta dot onet dot pl

--- 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