[Issue 19288] New: memory corruption in attached threads

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Oct 5 17:21:00 UTC 2018


https://issues.dlang.org/show_bug.cgi?id=19288

          Issue ID: 19288
           Summary: memory corruption in attached threads
           Product: D
           Version: D2
          Hardware: All
                OS: Windows
            Status: NEW
          Severity: critical
          Priority: P1
         Component: druntime
          Assignee: nobody at puremagic.com
          Reporter: ilyayaroshenko at gmail.com

Info

=============

Confirmed issue targets are
Win64 and Win32. Posix sustems has not been tested for now.

dmd --version
DMD32 D Compiler v2.081.2

or

ldmd2 --version
LDC - the LLVM D compiler (1.11.0):
  based on DMD v2.081.2 and LLVM 6.0.1
  built with LDC - the LLVM D compiler (1.11.0)


clang++ --version
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

or latest MSVC (VS 2017)

=============

D DLL: stress_dlang_gc_dll.d

__gshared TestS[] testCollection;
__gshared int cnt;

struct TestS
{
    double d;
    ~this()
    {
        cnt++;
    }
}

export extern(C)
void test_dlang_gc(int len, int count)
{
    import core.stdc.stdio;
    foreach(i; 0 .. count)
    {
        testCollection = new TestS[len];
    }
}
pragma(msg, size_t.sizeof * 8);
// C# and C++ threads don't work
version(all)
{

    version (Windows)
    {
        import core.sys.windows.dll;

        mixin SimpleDllMain;
    }
}
// D Threads work well:
else
{
    import core.thread;

    const int testCount = 10;
    const int threadArrayLength = 18;

    pragma(msg, size_t.sizeof * 8);

    void main()
    {
        Thread[threadArrayLength][testCount] threads;
        foreach(j; 0 .. testCount)
        {
            foreach(i; 0 .. threadArrayLength)
            {
                threads[j][i] = new Thread({
                    import std.random;
                    auto len = uniform(90, 110);
                    auto count = uniform(90, 110) * 10;
                    test_dlang_gc(len, count);
                }).start();
            }
            threads[j][1].join;
        }
        foreach(j; 0 .. testCount)
            foreach(i; 0 .. threadArrayLength)
                if (i != 1)
                    threads[j][i].join;
    }
}

===============

C++ MAIN: stress_dlang_gc.cpp

#include <iostream>
#include <windows.h>
#include <thread>
#include <random>

typedef void(__stdcall *f_funci)(int, int);
const int testCount = 10;
const int threadArrayLength = 18;
f_funci funci;
std::thread* dlangThreads;


int main()
{
  HINSTANCE hGetProcIDDLL = LoadLibrary("stress_dlang_gc_dll.dll");

  if(!hGetProcIDDLL)
  {
    std::cout << "could not load the dynamic library\n" << std::endl;
    return EXIT_FAILURE;
  }

  // resolve function address here
  funci = (f_funci)GetProcAddress(hGetProcIDDLL, "test_dlang_gc");
  if (!funci)
  {
    std::cout << "could not locate the 'test_dlang_gc' function" << std::endl;
    return EXIT_FAILURE;
  }

  dlangThreads = new std::thread[threadArrayLength * testCount];
        for(int j = 0; j < testCount; j++)
        {
                for (int i = 0; i < threadArrayLength; i++)
                {
        dlangThreads[j * threadArrayLength + i] = std::thread([] {
          std::random_device rd;  //Will be used to obtain a seed for the
random number engine
          std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded
with rd()
          std::uniform_int_distribution<> rnd(90, 110);
          int len = rnd(gen);
          int count = rnd(gen) * 10;
          funci(len, count);
        });
                }
    dlangThreads[j * threadArrayLength + 1].join(); // do not wait others
        }

  for (int j = 0; j < testCount; j++)
      for (int i = 0; i < threadArrayLength; i++)
          if (i != 1)
              dlangThreads[j * threadArrayLength + i].join();

  delete[] dlangThreads;

  std::cout << "test passed" << std::endl;

  return EXIT_SUCCESS;
}

===================

D Compile:

dmd -m64 -shared .\stress_dlang_gc_dll.d
or
ldmd2 -m64 -shared .\stress_dlang_gc_dll.d

C++ compile:
clang++ -Xclang -flto-visibility-public-std -o .\stress_dlang_gc.exe
.\stress_dlang_gc.cpp
or
with MSVC

Test script:
==================

for($counter = 1; $counter -le 1000; $counter++)
{
    $Result = .\stress_dlang_gc.exe
    $r = $?
    echo "counter = $counter"
    if (-Not($r))
    {
        echo "FAILED"
        break
    }
}

--


More information about the Digitalmars-d-bugs mailing list