Hello group!

We are experiencing problems with boost::weak_ptr in a multi-threaded environment. It looks that the lock on the ref counting doesn't work well with weak_ptr in release build.

configuration :
Windows 2000 SP4
VC6 SP5
boost 1.33.1

In summary, it seems that add_ref_lock in sp_counted_base_w32.hpp has a bug in release. In disassemblies, we observe :

01   lea         esi,[eax+4]
02   mov         eax,dword ptr [esi]
03   test        eax,eax
04   je          TestWeakPtr+0E4h (00401244)
05   lea         ecx,[eax+1]
06   mov         edx,esi
07   lock cmpxchg dword ptr [edx],ecx
08   mov         ecx,eax
09   cmp         ecx,eax
10   je          TestWeakPtr+7Dh (004011dd)

At line 08, you'll see that we move eax into ecx and after (line 09) we compare ecx and eax that are obviously the same which will destruct prematurely our pointer. In attachement, I send a complete program reproducing the bug with VC6 in release.

It is probably a bug in VC6. But is it caused by a bad use? is it simply a "bug" in boost 1.33.1?

By the way, we can remove the "bug" by simply "patching" add_ref_lock implementation like this :

bool add_ref_lock() // true on success
{
    for( ;; )
    {
        long tmp = static_cast< long const volatile& >( use_count_ );
        if( tmp == 0 ) return false;
        long tmp2 = tmp + 1;
        if(InterlockedCompareExchange ( &use_count_, tmp2, tmp ) == tmp2 - 1 )
            return true;
    }
}

Thank you for any suggestion!

--
Alain Cormier
alain.work@gmail.com