-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid throwing from a destructor in PartitionLoops.cpp #8767
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
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.
LGTM. Today I learned that destructors are always by default noexcept.
|
Going to investigate the memory leak reported here. |
|
I went in and built llvm-symbolizer (and updated the build master so it will do it automatically going forward) to get stack traces to the leaking allocations... looks like it's finding leaks in other parts of the compiler unrelated to PartitionLoops. Worse, I wasn't able to reproduce the leak on either my Ubuntu 24.04 x86 desktop or my MacBook. On Ubuntu, Valgrind says everything is "still reachable" (some of the LLVM command-line options stuff stores new'd pointers in global, static memory, apparently). I wonder if this is a consequence of throwing in a destructor? Here's the more detailed leak report: Details |
It doesn't sound all that crazy that the compiler just gives up on cleanup and calling destructors if a new exception is thrown. You'd get an explosion of combinations of cleanup code where stuff can break if the destructors start throwing too... Although I would argue that this is indeed a desirable feature in this simple scenario. Jai's |
|
I suggest wrapping the actual mutation code in a helper function, and doing the error checking for the loop partition mutation manually outside that wrapper, without relying on a destructor. |
Same with Zig, which is a language that actually, y'know, exists 😉
I'd be more comfortable making a large refactoring if I could tell that it actually fixed the problem. I can't reproduce the issue locally yet. |
|
It claims a For node is leaked. The exception is thrown inside a For IRMutator method. Seems like this is probably real. Maybe there's UB here so it's not a guaranteed leak and that's why you can't repro locally? |
|
+1 to Martijn's suggestion, which I think amounts to renaming this method visit_for, having it additionally return if partitioning happened, and doing the checking in visit(const For *). Doing it blind and seeing if it appeases the buildbot sucks but might be the fastest option. |
57a4f8a to
69afa21
Compare
|
The new Error-marco with for-loop trick didn't fix this problem? |
Unfortunately, no. Seems like the problem runs deeper. I'm going to build Halide using LLVM main and see if that reproduces the issue. |
|
I built the test on macOS using LLVM 22 (main) and its ASAN-enabled runtime. I only see perfectly spurious leaks (see details below). I'm at a loss as to why leaks are being detected here... Details |
|
It appears the test has started working again! I believe this to have been an LLVM main injection all along... https://buildbot.halide-lang.org/master/#/builders/273/builds/60 However, it looks like we checked #8689 in with a failing test. The |
Is this because of IRVisitor / IRMutator recursions going too deep? Can we increase stack size further? |
We normally do, but not on ASAN. There's explicit logic in there that disables |
|
Failures are unrelated. The new |
Destructors are
noexcept(true)by default and throwing (asuser_errordoes) in such a function always callsstd::terminate. That made this particular exception non-recoverable in user code.The included test aborts without the patch to PartitionLoops.cpp.