Bug 18063 – thread_attachThis returns dangling pointer

Status
NEW
Severity
major
Priority
P2
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2017-12-11T11:05:42Z
Last change time
2024-12-07T13:37:49Z
Keywords
pull
Assigned to
No Owner
Creator
Ali Cehreli
See also
https://issues.dlang.org/show_bug.cgi?id=22358
Moved to GitHub: dmd#17354 →

Comments

Comment #0 by acehreli — 2017-12-11T11:05:42Z
thread_detachThis fails to reset the thread-local sm_this pointer; so, thread_attachThis hands out a stale one. The following call sequence from a non-D thread is sufficient to reproduce the issue: thread_attachThis(); thread_detachThis(); thread_attachThis(); Although, the effects of the undefined behavior shows up after exercising the GC. Pull request including a test program is coming shortly...
Comment #1 by acehreli — 2017-12-11T11:19:37Z
Comment #2 by acehreli — 2017-12-12T00:23:59Z
Comment #3 by dlang-bot — 2020-03-01T23:02:00Z
@MoonlightSentinel created dlang/druntime pull request #2966 "Revive 1989: Thread detach stability" fixing this issue: - Issue 18063 - Do not pthread_detach non-D threads - Fix issue 18063 - thread_attachThis returns dangling pointer https://github.com/dlang/druntime/pull/2966
Comment #4 by thomas.bockman — 2021-10-05T20:35:13Z
It appears to be a race condition between `thread_attachThis` and `GC.collect`. Serializing them prevents the crash: ////////////////////////////////////////////////// import core.sys.posix.pthread; import core.memory; import core.sync.mutex; import core.thread; import std.stdio; enum allocCount = 1000; enum allocSize = 1000; enum threadCount = 100; enum collectCount = 1000; shared Mutex serialize; shared static this() { serialize = new shared Mutex; } extern(C) void* foo(void*) { serialize.lock_nothrow(); thread_attachThis(); serialize.unlock_nothrow(); scope(exit) thread_detachThis(); foreach(_; 0..allocCount) { new int; new int[allocSize]; } writeln(`foo done`); return null; } void main() { pthread_t thread; foreach(_; 0..threadCount) { auto status = pthread_create(&thread, null, &foo, null); assert(status == 0); foreach(i; 0..collectCount) { serialize.lock_nothrow(); GC.collect(); serialize.unlock_nothrow(); } pthread_join(thread, null); } writeln(`main done`); } //////////////////////////////////////////////////
Comment #5 by thomas.bockman — 2021-10-05T20:36:11Z
(In reply to thomas.bockman from comment #4) > It appears to be a race condition between `thread_attachThis` and > `GC.collect`. Serializing them prevents the crash: Oops, I meant to submit that to bug 22358: https://issues.dlang.org/show_bug.cgi?id=22358
Comment #6 by robert.schadek — 2024-12-07T13:37:49Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17354 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB