digitalmars.D.bugs - [Issue 19288] New: memory corruption in attached threads
- d-bugmail puremagic.com (166/166) Oct 05 2018 https://issues.dlang.org/show_bug.cgi?id=19288
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 puremagic.com Reporter: ilyayaroshenko 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); 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 } } --
Oct 05 2018