-
-
Notifications
You must be signed in to change notification settings - Fork 747
Fix Issue 18024 - checkedint.Warn should be @safe #5928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Thanks for your pull request, @wilzbach! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + phobos#5928" |
44a4d9a to
f0309d5
Compare
f0309d5 to
c8ad139
Compare
std/experimental/checkedint.d
Outdated
| import std.stdio : stderr; | ||
| import std.stdio : File; | ||
| static: | ||
| private @property File trustedStderr() @trusted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File is unsafe for a reason. Checked!Warn and Checked!Abort are currently thread unsafe and this will mark them as good to go.
I'm of the opinion that trustedStdout was a huge mistake we're still paying for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a private property and only used for printing to stdout within Warn.
c8ad139 to
76d45ee
Compare
76d45ee to
35fa2d9
Compare
|
So can we all agree on a method that writes to |
|
import std.algorithm;
import std.experimental.checkedint;
import std.parallelism;
import std.range;
import std.stdio;
void main()
{
stderr = File("/dev/null", "w");
foreach(t; 100_000.iota.map!(a => checked!(Warn)(a)).parallel)
{
auto a = (t * 10000 * 1000 * 1000).get;
}
}I highly recommend that we go with my suggestion in the bug report
|
|
Ping |
35fa2d9 to
a33cf02
Compare
OK. Finally found time to rebase this and change to this. Ehm Anyhow do you have a better idea for quick |
|
|
Thanks a lot for your ideas, but I still think that if Or you know Exception's toString could support ranges or writer-based
Week, ideally there will be even RCString one day...
That's a good idea, but wouldn't this lead to a slight overhead in startup and memory consumption for everyone using checked?
It's possible to catch AssertErrors even though it's officially undefined, it works quite well and is needed for e.g. Vibe.d when you don't want a single fiber crash to crash your entire web server. |
|
Another option is to push for https://issues.dlang.org/show_bug.cgi?id=15100 |
std/experimental/checkedint.d
Outdated
|
|
||
| /// | ||
| @system unittest | ||
| unittest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs an annotation
JackStouffer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Just needs a changelog entry detailing the change/breakage.
a33cf02 to
38d09f3
Compare
Added. |
|
Ping @andralex |
andralex
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One really nice thing about the default Checked/checked was that it was issuing an explanatory message before terminating the program. That was a massive improvement over "Bus error", "Division by zero" and similar messages with little additional detail provided by lower-level facilities.
In release mode, assert(0, msg) does not print msg and provides no explanation. We could argue that this behavior should be changed (I think it should); we worry about things like the size of messages and code way too much for this era. Or we could look for a trusted means to write to stderr before aborting. Whatever we do, we should keep the nice behavior.
| $(REF Abort, std,experimental,checkedint) no longer calls $(REF writeln, std,stdio) on an exception | ||
| and immediately terminates the program with an `AssertError`. | ||
|
|
||
| The old behavior of printing the error message to stdout before aborting the program is available as a new $(REF Debug, std,experimental,checkedint) hook. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit of rationale would be useful
| fails every incorrect operation with `assert(0, msg)`. It is the default | ||
| second parameter, i.e. `Checked!short` is the same as | ||
| $(D Checked!(short, Abort)). | ||
| `Checked!(short, Abort)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multi-word phrases in backquotes are dangerous. Some editors support reflowing text. When that feature is used during document editing, the backquotes may be split across different lines, leading to wrong formatting. I use backquotes only for single-word code snippets.
@JackStouffer Can you explain further? I tried running your example at various optimization levels with DMD and LDC and couldn't get it to segfault, although I was able to inconsistently get |
|
https://run.dlang.io/is/QAzYqy To make a long story short, the ref counting causes a race condition. I'm not able to get it to happen master either, but the code hasn't changed so I'm not convinced it's fixed. |
👍 (
Yeah that's what I initially did. (though it now stops the world to be able to claim being allowed to write to stderr safely which I'm still not sure whether whether such big hacks are really necessary) |
|
The thrust should go into fixing |
|
The problem that came up with locking is that it was seen as a performance penalty to those using it in a non-threaded environment. The obvious answer to that is only use mutexes when it’s shared. But, as we’ve already seen, shared is not viable for file. If you’re willing to live with the performance penalty I would love to see this happen |
Maybe we could get away with just atomic refcounting, but that's still a penalty.
Then maybe two different structs, Although one might ask what we're gaining from |
Yes and that came up as well. But again,
There are reasons, but it's irrelevant now that we're stuck with it. |
|
If changing the type of stdout/stderr is a non-starter how about thread-locals? |
|
Also backwards incompatible IIRC. The best option here is to add locks or atomic ops in File |
|
We should be able to cope with the inefficiency in copying. Nevertheless, what are the incompatibilities? |
|
Anything which relies on the fact that Also, you have to ask how making them thread locals would work, as So to reiterate, we're really only left with two practical options
|
Right now they're lazily initialized EDIT |
|
Not sure what you mean here because you can't reassign C's |
|
@JackStouffer I guess freopen does that. |
|
@JackStouffer That appears to be platform-dependent. https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html
fclose (stdout);
stdout = fopen ("standard-output-file", "w");
|
This should be fine. |
Silly me, I assumed the implementation of standard output be standardized. |
|
Now, after #6382 is merged, I still think there is still something blocking this: the issue of the unsafe reassignment of stdout/in/err. The most viable solution as I see to the problem of possible data races in stderr reassignment is to modify It would then be prudent to mark these property functions as Thoughts? |
How could reassigning a global variable possibly be |
It wouldn't, silly mistake. |
38d09f3 to
a73d078
Compare
|
This has been fixed by: #7909 |
Same pattern as in
phobos/std/stdio.d
Lines 3575 to 3578 in 5964600
Maybe instead of the
trustedStdoutworkaroundmakeGlobalshould have been made@safe?phobos/std/stdio.d
Line 4612 in 5964600