Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive

Fix crash in destructor of detached thread#2334

Merged
dlang-bot merged 2 commits intodlang:stablefrom
mihails-strasuns:fix-detach-termination
Oct 25, 2018
Merged

Fix crash in destructor of detached thread#2334
dlang-bot merged 2 commits intodlang:stablefrom
mihails-strasuns:fix-detach-termination

Conversation

@mihails-strasuns
Copy link
Contributor

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

Expectation is that after thread is detached from druntime, it becomes
responsibility of external environment to terminate it properly (for
example, by calling join from C/C++ code).

However, Thread object for that thread will still remain and will
eventually be collected by GC. Destructor tries to call pthread_detach
unconditionally but it is undefined behaviour if thread was alread
joined before (see man pthread_detach).

This fix invalidates thread object when it is detached so that
destructor can't conflict with external thread management code.

@dlang-bot
Copy link
Contributor

dlang-bot commented Oct 18, 2018

Thanks for your pull request and interest in making D better, @mihails-strasuns! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
19314 normal Thread object destruction may result in UB

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "stable + druntime#2334"

@mihails-strasuns
Copy link
Contributor Author

Looks like this clashes with internal thread attaching/detaching. Will investigate more.

@mihails-strasuns
Copy link
Contributor Author

mihails-strasuns commented Oct 18, 2018

Right, so regular Thread.join still should work after detaching as it is not only used externally. Choosing between few alternatives, will update PR soon.

@mihails-strasuns
Copy link
Contributor Author

Updated with a less intrusive version which adds additional flag. Will add test case after #2333 is merged as they share similar pattern.

@Laeeth
Copy link
Contributor

Laeeth commented Oct 19, 2018

Blocking deployment of analytic tools across the firm.

@@ -1860,6 +1868,8 @@ private:
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that this was used previously to see if the thread was detached. You can either replace this
with if (t.m_detached == false) or use this in the destructor directly.

@PetarKirov
Copy link
Member

@mihails-strasuns Can you add a test case? Also there's a typo in your commit message ("alread").

@mihails-strasuns
Copy link
Contributor Author

Yup, was waiting for the other PR to get merged. Will update in a moment.

@mihails-strasuns
Copy link
Contributor Author

Updated

Copy link
Contributor

@jacob-carlborg jacob-carlborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should contain a changelog entry or a reference to a bugzilla issue. Otherwise it won't appear in the changelog.

@mihails-strasuns
Copy link
Contributor Author

@jacob-carlborg Fixes https://issues.dlang.org/show_bug.cgi?id=19314 ?

@jacob-carlborg
Copy link
Contributor

The commit message needs to start with "Fix issue XXX" where "XXX" is the bugzilla issue. The dlang-bot will post a message in the PR when it has been properly connected to the bugzilla issue.

@mihails-strasuns
Copy link
Contributor Author

Such a choosy bot :X

@dlang-bot dlang-bot added the Bug Fix Include reference to corresponding bugzilla issue label Oct 23, 2018
@wilzbach
Copy link
Contributor

Such a choosy bot :X

This is needed for parsing the git commit messages of all repos for a release.

See also: https://github.com/dlang/dlang-bot#automated-references

@mihails-strasuns
Copy link
Contributor Author

My remark was about how limited are supported formats of mention :) I doubt that supporting few more common patterns would result in lot of false positives.

@n8sh n8sh dismissed jacob-carlborg’s stale review October 23, 2018 23:57

Added reference to issue number as requested.

{
if ( m_addr == m_addr.init )
bool no_context = m_addr == m_addr.init;
bool not_registered = !next && !prev;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's only one registered thread its next and prev would also be null, but it appears to me that we don't need to worry about this because it could only happen in the destructor of the main thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That can potentially happen when being called for C - main thread can be detached too. I have adjusted the PR and also fixed remove method to take that into account.

Mihails Strasuns added 2 commits October 24, 2018 10:18
Fix issue 19314

Expectation is that after thread is detached from druntime, it becomes
responsibility of external environment to terminate it properly (for
example, by calling `join` from C/C++ code).

However, `Thread` object for that thread will still remain and will
eventually be collected by GC. Destructor tries to call `pthread_detach`
unconditionally but it is undefined behaviour if thread was already
joined before (see `man pthread_detach`).
Previously `remove` implementation would early return if removed thread
is the only element in the registered list (and thus has no prev/next
references)
@dlang-bot dlang-bot merged commit ec7b659 into dlang:stable Oct 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Bug Fix Include reference to corresponding bugzilla issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants