Conversation
|
Thanks for your pull request and interest in making D better, @MoonlightSentinel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
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 referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. 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 + dmd#10560" |
src/build.d
Outdated
| /// Aborts the current build | ||
| void abortBuild() | ||
| { | ||
| throw new Exception("Build failed!"); |
There was a problem hiding this comment.
You may want to throw a specific Exception type for each build failure cause and optionally include additional information.
There was a problem hiding this comment.
Added the possibility to specify a custom message but custom exceptions for every possible build failure seem overkill IMHO. The only intent of this change is to enable destructors and scope(...) statements which will be skipped by exit.
a3cd147 to
a0c46f2
Compare
|
So originally we were throwing exceptions in build.d, but we changed it because we don't want to print a stacktrace to build.d when this occurs. Maybe you could catch the exception before it gets caught by the default exception handler and prints the stacktrace? |
@marler8997 Done |
25978b3 to
bf63dc0
Compare
src/build.d
Outdated
| */ | ||
| BuildException abortBuild(string msg = "Build failed!") | ||
| { | ||
| return new BuildException(msg); |
There was a problem hiding this comment.
You could also throw here. it looks weird to throw both at the callsite and inside the function, but doing both has benefits even if the caller's throw never actually gets executed.
There was a problem hiding this comment.
Indeed, double throw would be really weird. How would that be beneficial?
There was a problem hiding this comment.
someone might accidently call abortBuild without throw abortBuild, thinking that it would exit the program (since it's called abortBuild). Since error conditions like this are rarely tested, it's good to make these code paths as "full proof" as you can.
If you throw inside the function but still return an Exception type (that will never actually return), then caller can choose to use the explicit throw or not, depending on if they need that control flow. Take this example
int returnInt()
{
if (foo)
{
return 0;
}
abortBuild();
}In this case you would get a compile error because the end of the function doesn't return anything. However, if abortBuild returns an Exception type even though it never returns, then you can just do throw abortBuild() and the compiler will be happy.
Note that there's been some discussion about adding a trait or a special return type for functions that means "noreturn", but D doesn't have that yet. This is sort of a workaround for not having that feature.
There was a problem hiding this comment.
This can be an easy mistake to make as well:
void foo()
{
if (somethingWentWrong)
abortBuild("oh no");
okWereGood();
}If you throw inside the function, then this works as one would expect from just looking at the code without going into the function definitions.
If you don't want to throw inside abortBuild, then it's better to call it something like makeBuildError, as it's not really aborting the build, just returning an error that you need to throw yourself. I know you named it abortBuild as you were initially throwing so the name is only confusing because of my suggestion :)
There was a problem hiding this comment.
Clever. I'll revert to throwing inside of abortBuild but keep the fake return value to allow throw abortBuildat the callsite
bf63dc0 to
80d890f
Compare
|
Changed cxx-unittest to use |
80d890f to
4f87993
Compare
|
Auto-merge toggled on |
|
I've noticed that the new |
Do you have some clues under which consitions the deadlock appeared? (System, Target, ...) |
|
I tried reproducing the hang but couldn't. I can reproduce a similar issue today by injecting an error into the backend. Sometimes it will fail with an error, and sometimes we'll get an uncaught exception like this: In any case, with this change I no longer get this uncaught exception, so I think the hang is probably fixed as I think it's closely related to this uncaught exception. |
|
Is build.d using some kind of "fork", maybe also indirectly when spawning other processes? Then there might be a couple of issues that appeared with the parallel GC (some not directly related). These are fixed in 2.089 (dlang/druntime#2816, dlang/druntime#2817, dlang/druntime#2813), but it seems 2.088 is used by the builds here. |
|
@rainers that seems likely as I was no longer getting the hang when trying to reproduce today. Now I only get the uncaught exception on |
|
So maybe we should bump the version that AUTO_BOOTSTRAP uses to 2.089 then to avoid issues on the Buildkite CI? |
|
It was mostly an annoyance during development. Most CI's should just timeout if a failure occurs and it hangs so not a huge deal for them. |
Might be worth a try. I've also seen a similar error in the DAutoTest logs recently.
It can block other PRs if it waits for the timeout instead of failing fast. I think it also obscures the actual error. |
This PR enables
build.dto handle build failures instead of terminating immediatly (without caring about running processes, temporary files, ...).This allows build.d e.g. to provide additional information about a failed target