Bug 20680 – core.thread.Thread leaks OS handle when not joined

Status
NEW
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2020-03-17T11:35:39Z
Last change time
2024-12-07T13:40:06Z
Assigned to
No Owner
Creator
Tomáš Chaloupka
Moved to GitHub: dmd#17400 →

Comments

Comment #0 by chalucha — 2020-03-17T11:35:39Z
When thread is just created and forgotten about - which is pretty common case for worker threads (ie with std.concurrency.spawn) it leaks the OS handle (at least on windows) as CloseHandle is not called in Thread destructor. My guess is that it's because of these lines: * https://github.com/dlang/druntime/blob/master/src/core/thread/osthread.d#L304 * https://github.com/dlang/druntime/blob/master/src/core/thread/osthread.d#L697 The last line yields true so CloseHandle isn't called in Thread destructor. See the test case below and watch what happens with process handles ie in sysinternals procexp or handles utilities. ```D import core.thread; import core.time; import std; extern(C) __gshared string[] rt_options = [ "gcopt=parallel:0" ]; void main() { writeln("press enter to start"); readln(); Thread[10] threads; foreach (i; 0..10) threads[i] = new Thread(&threadFn).start(); Thread.sleep(1.seconds); // make sure they are done foreach (i; 0..10) { // threads[i].join(); # if joined, OS handle is closed as expected destroy(threads[i]); # enforce destructors to be called } writeln("threads disposed, press enter to exit"); readln(); } void threadFn() { } ```
Comment #1 by mail — 2020-05-25T11:01:56Z
This is the case as well under Linux. With GDB attached I have put a breakpoint at the core.thread.osthread.Thread's destructor and confirmed it doesn't get run (I spawned 100k threads and let them run till finish). As a workaround I am calling `pthread_detach(pthread_self);` right before the thread terminates. This is not a good solution though since the Thread's destructor (if it did ran), would also call pthread_detach, which results in undefined behaviour. Better would be to do a thread_detachThis as well, since that will cause a different branch in the Thread's destructor and avoid the call to pthread_detach. Sadly, using thread_detachThis and the pthread_detach I get spurious crashes in std.concurrency's tls module teardown (sometimes).
Comment #2 by schveiguy — 2021-11-17T14:45:09Z
When linking to github, use the `y` command to change the link to a hash-based link, otherwise your links get stale. For reference, here are the two links: https://github.com/dlang/druntime/blob/19ef6336d1940e770d696dc71f7605eb3f618a85/src/core/thread/osthread.d#L304 https://github.com/dlang/druntime/blob/19ef6336d1940e770d696dc71f7605eb3f618a85/src/core/thread/osthread.d#L697 Can you test again? the code has changed quite a bit since then, the destructor looks rewritten.
Comment #3 by chalucha — 2021-11-17T17:36:18Z
(In reply to Steven Schveighoffer from comment #2) > When linking to github, use the `y` command to change the link to a > hash-based link, otherwise your links get stale. > > For reference, here are the two links: > > https://github.com/dlang/druntime/blob/ > 19ef6336d1940e770d696dc71f7605eb3f618a85/src/core/thread/osthread.d#L304 > https://github.com/dlang/druntime/blob/ > 19ef6336d1940e770d696dc71f7605eb3f618a85/src/core/thread/osthread.d#L697 > > Can you test again? the code has changed quite a bit since then, the > destructor looks rewritten. Yes I can still confirm it on both windows and linux. Tried with dmd-2.098.0 on windows and build from current master on linux. Added some logging to the Thread destructor with the output: ```D press enter to start ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() ~Thread() threads disposed, press enter to exit ~Thread() passed detach ``` So currently, it won't pass this https://github.com/dlang/druntime/blob/abd43eb4e760667fc4b1ebe1fe07d29340265596/src/core/thread/osthread.d#L292 And sorry for not permanent links, younger me hasn't known all he knows now ;-)
Comment #4 by robert.schadek — 2024-12-07T13:40:06Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17400 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB