bloomberg / bde

Basic Development Environment - a set of foundational C++ libraries used at Bloomberg.
Apache License 2.0
1.68k stars 318 forks source link

Crash With MSVC 2019 #254

Closed dharesign closed 4 years ago

dharesign commented 4 years ago

Overview

There seems to be erroneous code generation in MSVC 2019 (and 2017), when compiling the following code with /Ob0: https://github.com/dharesign/bde/commit/0ebd79270f828db82c233b86276c96ff883ea113

The code appears to end up memcpy-ing a bsl::map object, resulting in its internal state (pointers to heap objects) being invalid.

When compiling with /Ob1 the issue goes away: https://github.com/dharesign/bde-tools/commit/140dd5b4a94533a1312e70c76f6f007955d73528

The code posted is a minimal example of the issue. The Derived class appears to need two base classes for the issue to occur. The bound function needs to be a member function. A similar free function taking a Derived * as the first parameter doesn't exhibit the crash.

Using native std::bind doesn't crash.

To Reproduce

With MSVC 2019, CMake, and Git Bash installed:

git clone https://github.com/bloomberg/bde
git clone https://github.com/bloomberg/bde-tools

cd bde
git remote add dharesign https://github.com/dharesign/bde
git checkout dharesign/trigger-crash

export PATH=../bde-tools/bin:$PATH
eval `bde_build_env.py --build-type=Debug --cpp-std=17 --abi-bits=32`
cmake_build.py configure
cmake_build.py build --tests=run --targets bdlf_bind.t

The test fails with an access violation:

Test project C:/dev/code/bde/_build/windows-windows_nt-x86_64-10.0-msvc-2019-dbg_exc_mt_cpp17
    Start 298: bdlf_bind.t
1/1 Test #298: bdlf_bind.t ......................***Failed    1.71 sec
[15:02:38] TEST START
[15:02:38] CASE  1: SUCCESS
[15:02:38] CASE  2: SUCCESS
[15:02:38] CASE  4: SUCCESS
[15:02:38] CASE  3: SUCCESS
[15:02:38] CASE  5: SUCCESS
[15:02:38] CASE  6: SUCCESS
[15:02:39] CASE  7: SUCCESS
[15:02:39] CASE  8: FAILURE (rc -1073741819)

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   1.86 sec

The following tests FAILED:
        298 - bdlf_bind.t (Failed)

The following works around the crash:

cd bde-tools
git remote add dharesign https://github.com/dharesign/bde-tools
git checkout dharesign/fix-crash
dharesign commented 4 years ago

Note that internally we determined that it was due to an alignas. If the alignas is removed, the problem goes away.

https://gist.github.com/dharesign/25b0d324ba48314eb4c683910c7b199f is a complete test case that simplifies out all of the BDE code.

Note that removing MemFn (and thus storing a ConPxy<FN> in Bound) also makes the problem go away.

dharesign commented 4 years ago

Even shorter version showing the same issue: https://godbolt.org/z/MGFFRB. The generated code for void f(S) in /Ob0 has a _memcpy before calling S::~S.

osubboo commented 4 years ago

I believe this issue was addressed via internal PR. Closing.