Reid Kleckner via llvm-dev
2020-Dec-09 20:14 UTC
[llvm-dev] Catching exceptions while unwinding through -fno-exceptions code
Using existing personality functions requires emitting an LLVM IR cleanup around every function when building in this -fterminate-exceptions mode. Then all functions would have IR like this: invoke void @foo(...) unwind to %terminate invoke void @bar(...) unwind to %terminate ... landingpad cleanup ... call void @myterminate() On Tue, Dec 8, 2020 at 12:56 PM James Y Knight <jyknight at google.com> wrote:> Why is adding a new personality function useful? Can't you share a single > LSDA table for every noexcept function in a TU (both those implicitly > noexcept due to -fno-exceptions and for those marked "noexcept")? > > On Tue, Dec 8, 2020 at 1:05 PM Reid Kleckner via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> I would suggest using a custom personality function for this. It will >> optimize better and be much smaller than using a standard personality >> function. It saves the LSDA tables. >> >> LLVM supports custom personality functions, so only clang changes are >> required. You could either do something like add a flag to override the EH >> personality with a custom one, or come up with a new dedicated >> fno-exceptions termination personality and add it to compiler-rt. >> >> On Mon, Dec 7, 2020 at 3:31 PM Modi Mo via llvm-dev < >> llvm-dev at lists.llvm.org> wrote: >> >>> If you don’t need to capture more information and can just terminate, >>> you can directly register std::terminate as the personality routine as >>> opposed to __gxx_personality_v0 or __CxxFrameHandler3/4 (Windows) which >>> lets you omit other metadata and work cross-platform. >>> >>> >>> >>> Modi >>> >>> >>> >>> *From: *llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Everett >>> Maus via llvm-dev <llvm-dev at lists.llvm.org> >>> *Reply-To: *Everett Maus <evmaus at google.com> >>> *Date: *Monday, December 7, 2020 at 12:47 PM >>> *To: *"llvm-dev at lists.llvm.org" <llvm-dev at lists.llvm.org> >>> *Subject: *[llvm-dev] Catching exceptions while unwinding through >>> -fno-exceptions code >>> >>> >>> >>> Hey all: >>> >>> >>> >>> I wanted to bring up something that was discussed a few years ago around >>> the behavior of exceptions when interacting with code compiled with >>> -fno-exceptions. (In >>> https://lists.llvm.org/pipermail/llvm-dev/2017-February/109992.html and >>> https://lists.llvm.org/pipermail/llvm-dev/2017-February/109995.html) >>> >>> >>> >>> It's possible to compile (and link/etc.) code with -fexceptions for some >>> compilation units and -fno-exceptions for others. Unlike the behavior of >>> noexcept (which requires termination), this doesn't have a specified >>> behavior in the C++ standard as far as I can tell. However, it can lead to >>> memory leaks & other issues (e.x. with TSAN, it messes up the tracking of >>> the current stack frame). >>> >>> >>> >>> I'd be interested in looking into potentially doing the work to add an >>> option to clang/etc. to terminate when an exception traverses code compiled >>> with -fno-exceptions, instead of simply allowing the unwinder to walk >>> through the stack frame & leak memory/etc. (possibly behind a flag?). This >>> particular issue bit a team I work closely with, and I'd imagine it could >>> be causing subtle issues for other clang users. >>> >>> >>> >>> I'm mostly concerned with solving this on Linux/x86_64, although if >>> there's a way to solve it more generally I'm open to looking into doing >>> that instead. >>> >>> >>> >>> I /think/ the right place to change this (from the discussions I linked) >>> would be in the LLVM -> assembly layer, adding an appropriate >>> .gcc_except_table for functions that are determined to be unable to throw >>> exceptions (either due to noexcept or due to -fno-exceptions). Then the >>> unwinder would find .eh_frame but no entry in the .gcc_except_table and >>> should terminate (via __gxx_personality_v0). >>> >>> >>> >>> Am I understanding that correctly? What's the best way to propose this >>> sort of change to clang? (document/just try to look at putting together a >>> PR/other?) >>> >>> >>> >>> Alternatively--one other thing that occurred to me is that it could be >>> reasonably cheap to simply add try/catch blocks that report an UBSAN error >>> in all methods that shouldn't be able to throw an exception. This >>> obviously doesn't fix the code-generation problem and would lead to larger >>> binary sizes, but that seems less bad for an UBSAN build in particular. >>> That would likely meet my needs around wanting a way to automatically >>> detect this behavior/problem, but might not address the more generic issue. >>> >>> >>> >>> Thanks, >>> >>> -- >>> >>> --EJM >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201209/31cb0ed0/attachment.html>
Reid Kleckner via llvm-dev
2020-Dec-09 20:15 UTC
[llvm-dev] Catching exceptions while unwinding through -fno-exceptions code
Bleh, early send. We'd also have to overcome the issue of functions being nounwind with -fno-exceptions, which means LLVM would optimize those invokes to calls immediately. On Wed, Dec 9, 2020 at 12:14 PM Reid Kleckner <rnk at google.com> wrote:> Using existing personality functions requires emitting an LLVM IR cleanup > around every function when building in this -fterminate-exceptions mode. > Then all functions would have IR like this: > > invoke void @foo(...) unwind to %terminate > invoke void @bar(...) unwind to %terminate > ... > landingpad cleanup ... > call void @myterminate() > > On Tue, Dec 8, 2020 at 12:56 PM James Y Knight <jyknight at google.com> > wrote: > >> Why is adding a new personality function useful? Can't you share a single >> LSDA table for every noexcept function in a TU (both those implicitly >> noexcept due to -fno-exceptions and for those marked "noexcept")? >> >> On Tue, Dec 8, 2020 at 1:05 PM Reid Kleckner via llvm-dev < >> llvm-dev at lists.llvm.org> wrote: >> >>> I would suggest using a custom personality function for this. It will >>> optimize better and be much smaller than using a standard personality >>> function. It saves the LSDA tables. >>> >>> LLVM supports custom personality functions, so only clang changes are >>> required. You could either do something like add a flag to override the EH >>> personality with a custom one, or come up with a new dedicated >>> fno-exceptions termination personality and add it to compiler-rt. >>> >>> On Mon, Dec 7, 2020 at 3:31 PM Modi Mo via llvm-dev < >>> llvm-dev at lists.llvm.org> wrote: >>> >>>> If you don’t need to capture more information and can just terminate, >>>> you can directly register std::terminate as the personality routine as >>>> opposed to __gxx_personality_v0 or __CxxFrameHandler3/4 (Windows) which >>>> lets you omit other metadata and work cross-platform. >>>> >>>> >>>> >>>> Modi >>>> >>>> >>>> >>>> *From: *llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of >>>> Everett Maus via llvm-dev <llvm-dev at lists.llvm.org> >>>> *Reply-To: *Everett Maus <evmaus at google.com> >>>> *Date: *Monday, December 7, 2020 at 12:47 PM >>>> *To: *"llvm-dev at lists.llvm.org" <llvm-dev at lists.llvm.org> >>>> *Subject: *[llvm-dev] Catching exceptions while unwinding through >>>> -fno-exceptions code >>>> >>>> >>>> >>>> Hey all: >>>> >>>> >>>> >>>> I wanted to bring up something that was discussed a few years ago >>>> around the behavior of exceptions when interacting with code compiled with >>>> -fno-exceptions. (In >>>> https://lists.llvm.org/pipermail/llvm-dev/2017-February/109992.html >>>> and https://lists.llvm.org/pipermail/llvm-dev/2017-February/109995.html >>>> ) >>>> >>>> >>>> >>>> It's possible to compile (and link/etc.) code with -fexceptions for >>>> some compilation units and -fno-exceptions for others. Unlike the behavior >>>> of noexcept (which requires termination), this doesn't have a specified >>>> behavior in the C++ standard as far as I can tell. However, it can lead to >>>> memory leaks & other issues (e.x. with TSAN, it messes up the tracking of >>>> the current stack frame). >>>> >>>> >>>> >>>> I'd be interested in looking into potentially doing the work to add an >>>> option to clang/etc. to terminate when an exception traverses code compiled >>>> with -fno-exceptions, instead of simply allowing the unwinder to walk >>>> through the stack frame & leak memory/etc. (possibly behind a flag?). This >>>> particular issue bit a team I work closely with, and I'd imagine it could >>>> be causing subtle issues for other clang users. >>>> >>>> >>>> >>>> I'm mostly concerned with solving this on Linux/x86_64, although if >>>> there's a way to solve it more generally I'm open to looking into doing >>>> that instead. >>>> >>>> >>>> >>>> I /think/ the right place to change this (from the discussions I >>>> linked) would be in the LLVM -> assembly layer, adding an appropriate >>>> .gcc_except_table for functions that are determined to be unable to throw >>>> exceptions (either due to noexcept or due to -fno-exceptions). Then the >>>> unwinder would find .eh_frame but no entry in the .gcc_except_table and >>>> should terminate (via __gxx_personality_v0). >>>> >>>> >>>> >>>> Am I understanding that correctly? What's the best way to propose this >>>> sort of change to clang? (document/just try to look at putting together a >>>> PR/other?) >>>> >>>> >>>> >>>> Alternatively--one other thing that occurred to me is that it could be >>>> reasonably cheap to simply add try/catch blocks that report an UBSAN error >>>> in all methods that shouldn't be able to throw an exception. This >>>> obviously doesn't fix the code-generation problem and would lead to larger >>>> binary sizes, but that seems less bad for an UBSAN build in particular. >>>> That would likely meet my needs around wanting a way to automatically >>>> detect this behavior/problem, but might not address the more generic issue. >>>> >>>> >>>> >>>> Thanks, >>>> >>>> -- >>>> >>>> --EJM >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201209/6e6f4142/attachment.html>