weak_ptr reset corrupts shared_ptr with Intel Parallel Studio XE 2019 update 4,5 in VS2019?

weak_ptr reset corrupts shared_ptr with Intel Parallel Studio XE 2019 update 4,5 in VS2019?

Hello,

I got a strange error while using weak_ptr built with Intel Parallel Studio XE C++ 2019 update 4 and 5 embedded in VS2019.

Here is a sample of the code I use to reproduce the bug:

 

#include <iostream>
#include <memory>

using namespace std;

int main( int argc, char* argv[] )
{
    shared_ptr<int> sp = make_shared<int>( 42 );
    cout << *sp << endl;

    weak_ptr<int> wp = sp;
    cout << *wp.lock() << endl;

    wp.reset();
    cout << *sp << endl;

    return 0;
}

The first cout outputs "42" from the shared_ptr as expected;

the second cout outputs "42" from the weak_ptr as expected;

the third cout outputs 0xDDDDDDDD (or decimal equivalent...) rather than "42" showing that the shared_ptr was corrupted by the weak_ptr reset().

I observed this "phenomenon" in 64 bit/Debug only. It works fine in Release and in either Debug or Release in 32 bit. I also noticed that it worked correctly with our old Intel 2018 C++ compiler.

Does someone observe the same thing?

 

13 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Do you see the same error if you compile from the command line?

C:\temp> icl t.cpp /Od

Hi Hoang,

I do observe the problem when I call: > icl weakptr.cpp /Od /MDd

I do not observe the problem when I call > icl weakptr.cpp /Od /MD

(and I do not observe the problem when I call the line you suggested without /M....)

 

The command lines generated by VS2019 (that produce the bug) are:

Compiler:

icl.exe /c /Qm64 /ZI /nologo /W3 /Od /D __INTEL_COMPILER=1900 /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Qstd=c++17 /Fo"x64\Debug\\" /Fd"x64\Debug\vc142.pdb" /TP /FC weakptr.cpp

 

Linker:

xilink.exe -qm64 /OUT:"W:\SpikeSolutions\weakptr\x64\Debug\weakptr.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbccp32.lib /MANIFEST /manifest:embed /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"W:\SpikeSolutions\weakptr\x64\Debug\weakptr.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"W:\SpikeSolutions\weakptr\x64\Debug\weakptr.lib" /MACHINE:X64 x64\Debug\weakptr.obj

 

Note that all these arguments are generated by the IDE, I just selected x64/Debug...

I don't have VS2019 installed, but tried "icl t.cpp /Od /MDd" on VS2017:

C:\temp>icl t.cpp /Od /MDd
Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

t.cpp
Microsoft (R) Incremental Linker Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:t.exe
t.obj

C:\temp>t.exe
42
42
42

C:\temp>

 

Would you suggest it is a problem with the coupling with VS2019? Could be.

However, I tried the exact same snippet with VS2019 and it worked fine:

> cl /Od /MDd weakptr.cpp

> cl /Od /MD weakptr.cpp

 

My understanding is that icl and cl use the same stl. So I traced the code and I found that:

make_shared<int> calls ... new _Ref_count_obj<int> calls ... _Ref_count_base ctor...

_Ref_count_base has two members _Uses and _Weaks set to 1 and a constexpr cTor set to default:

// not copied verbatim...

class _Ref_count_base
{
public:
   Atomic_something _Uses = 1;   // I think it is actually unsigned long...
   Atomic_something _Weaks = 1;

protected:
   constexpr _Ref_count_base() noexcept = default;

// ...
}

This class is the base class for the reference counting. So, when the shared_ptr is constructed, both its counters are set to 1.

... but when using icl /MDd ! In that case, _Weaks remains 0. That causes a premature call to the destructor when weak_ptr.reset() is called.

After some tests, I suspect a problem when the default cTor is created in 64-bit/Debug.

Desn't that point to this direction?

Not sure. 

Which version of VS2019 you have installed? 

16.2.5

well, I also tried 16.3.2 and got the same problem.

Can you try the version which release prior to the compiler released date? (e.g. 16.1.1)

Actually, I don't have this version, sorry.

Also, I guess your programmers should backtrack the problem by themselves. They will save a lot of time.

If you tell me that a previous version of VS fixes the bug, I will try it as a temporary fix, of course.

Can you use /Od /MD as a workaround?

No, we have to use the debug version.

let me see if I can find a system with VS2019 installed as I didn't observe the problem with the same compiler and options on VS2017 as I previous mentioned:

C:\temp>icl t.cpp /Od /MDd
Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

t.cpp
Microsoft (R) Incremental Linker Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:t.exe
t.obj

C:\temp>t.exe
42
42
42

C:\temp>

 

 

Leave a Comment

Please sign in to add a comment. Not a member? Join today