<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:935671018;
mso-list-type:hybrid;
mso-list-template-ids:267671378 -1664069716 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
{mso-level-start-at:4;
mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;
mso-fareast-font-family:"Times New Roman";
mso-bidi-font-family:Calibri;}
@list l0:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l0:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l0:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l0:level5
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l0:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l0:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l0:level8
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l0:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l1
{mso-list-id:1156072918;
mso-list-type:hybrid;
mso-list-template-ids:1916684690 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l1:level1
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2
{mso-list-id:1383821904;
mso-list-type:hybrid;
mso-list-template-ids:-731993926 -634232662 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l2:level1
{mso-level-start-at:4;
mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;
mso-fareast-font-family:"Times New Roman";
mso-bidi-font-family:Calibri;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l2:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l2:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l2:level5
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l2:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l2:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l2:level8
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l2:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">> - Add a flag (-fterminate-exceptions?). This is because this is a very clear behavior change, so at least providing an opt-in/opt-out mechanism seems important. Possible option: make this an enum, have 'strict' = all exceptions crash,
'normal' = exceptions passing through methods that would require a cleanup /etc. terminate, none (default) = current behavior where things just leak/etc.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">+1. This definitely needs to be an opt-in feature over the current default behavior.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">> I think I'd prefer (and the team I partner with would prefer) /any/ exception passing from code compiled with -fexceptions to code compiled with -fno-exceptions to halt & return an error, even if the method wouldn't have participated
in exception handling (e.x. no classes that need to have destructors called, etc.) I think the most desirable behavior is "the program halts if exceptions pass through code compiled without exceptions enabled".<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Fully agreed. Mixing -fno-exceptions code with -fexceptions code is already dangerous and an anti-pattern. Propagating an exception successfully past code which is -fno-exceptions is asking for problems when LLVM has been explicitly instructed
to build with the knowledge that this scenario will not occur. To that end, a “non-strict” mode means the compiler has to reason about exceptions with -fno-exceptions passed which makes this seem more of a sub-flag for -fexceptions funnily enough.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">> I have verified that changing the personality function to std::terminate during code generation (via a boolean flag/etc.) does exactly what I'm looking for (but also has an impact on intermediate sizes of about what I expected).<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Nice! I’m curious about the impact of sizes. The relevant CIE + FDE with exceptions look like the following:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p style="margin:0in">From llvm-dwarfdump:<o:p></o:p></p>
<p style="margin:0in"> <o:p></o:p></p>
<p style="margin:0in">Has handler:<o:p></o:p></p>
<p style="margin:0in">000000a8 0000001c ffffffff CIE<o:p></o:p></p>
<p style="margin:0in"> Version: 1<o:p></o:p></p>
<p style="margin:0in"> Augmentation: "zPLR"<o:p></o:p></p>
<p style="margin:0in"> Code alignment factor: 1<o:p></o:p></p>
<p style="margin:0in"> Data alignment factor: -8<o:p></o:p></p>
<p style="margin:0in"> Return address column: 16<o:p></o:p></p>
<p style="margin:0in"> Personality Address: 00201a50 // gxx_personality_v0<o:p></o:p></p>
<p style="margin:0in"> Augmentation data: 03 50 1A 20 00 03 1B<o:p></o:p></p>
<p style="margin:0in"> <o:p></o:p></p>
<p style="margin:0in"> DW_CFA_def_cfa: reg7 +8<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_offset: reg16 -8<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_nop:<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_nop:<o:p></o:p></p>
<p style="margin:0in"> <o:p></o:p></p>
<p style="margin:0in">000000c8 00000024 00000024 FDE cie=00000024 pc=00001120...0000117f<o:p></o:p></p>
<p style="margin:0in"> LSDA Address: 002006b0<o:p></o:p></p>
<p style="margin:0in"><o:p> </o:p></p>
<p style="margin:0in">No Handler:<o:p></o:p></p>
<p style="margin:0in">00000000 00000014 ffffffff CIE<o:p></o:p></p>
<p style="margin:0in"> Version: 1<o:p></o:p></p>
<p style="margin:0in"> Augmentation: "zR"<o:p></o:p></p>
<p style="margin:0in"> Code alignment factor: 1<o:p></o:p></p>
<p style="margin:0in"> Data alignment factor: -8<o:p></o:p></p>
<p style="margin:0in"> Return address column: 16<o:p></o:p></p>
<p style="margin:0in"> Augmentation data: 1B<o:p></o:p></p>
<p style="margin:0in"> <o:p></o:p></p>
<p style="margin:0in"> DW_CFA_def_cfa: reg7 +8<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_offset: reg16 -8<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_nop:<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_nop:<o:p></o:p></p>
<p style="margin:0in"> <o:p></o:p></p>
<p style="margin:0in">00000018 00000010 0000001c FDE cie=0000001c pc=fffffc00...fffffc2f<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_advance_loc: 4<o:p></o:p></p>
<p style="margin:0in"> DW_CFA_undefined: reg16<o:p></o:p></p>
<p style="margin:0in"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Registering terminate/custom handler as a handler allows you to bypass the “L” Augmentation (since you don’t need an LSDA in such cases) so the total cost should be:<o:p></o:p></p>
<ol style="margin-top:0in" start="1" type="1">
<li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3">“P” augmentation string, 1 byte<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3">Encoding in Augmentation data of Personality Routine, 1 byte<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3">Relocation to Personality Routine, 4 bytes<o:p></o:p></li></ol>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">So it should add 6 bytes to every function. You can’t get away from adding an address to each function’s .eh_frame entry with how CIE/FDE works. I think the extreme that is possible is encoding this scenario in a new character in the Augmentation
String but that will severely limit what you can do outside of directly calling abort() along with changing the ABI
<span style="font-family:"Apple Color Emoji"">😃</span>.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">> From looking at the current location of exception-handling code, would it make more sense to have the personality function in libcxxabi (where __gxx_personality_v0 and friends live) or in compiler-rt (which doesn't seem to have any exception
handling code at the moment)?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It depends on the amount of functionality here and how language specific this is. As it stands I don’t think this is C++ specific and could extend to other llvm language targets which makes it a better candidate with compiler-rt. It would
be good to flesh out what behavior you want out of the personality function then go from there.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Modi<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">Everett Maus <evmaus@google.com><br>
<b>Date: </b>Tuesday, December 8, 2020 at 11:50 AM<br>
<b>To: </b>Reid Kleckner <rnk@google.com><br>
<b>Cc: </b>Modi Mo <modimo@fb.com>, "llvm-dev@lists.llvm.org" <llvm-dev@lists.llvm.org><br>
<b>Subject: </b>Re: [llvm-dev] Catching exceptions while unwinding through -fno-exceptions code<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">One additional question, actually:<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">From looking at the current location of exception-handling code, would it make more sense to have the personality function in libcxxabi (where __gxx_personality_v0 and friends live) or in compiler-rt (which doesn't seem to have any exception
handling code at the moment)?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Everett Maus<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Tue, Dec 8, 2020 at 11:26 AM Everett Maus <<a href="mailto:evmaus@google.com">evmaus@google.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">That makes sense. Really appreciate the feedback, all.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I think the approach I'll look at implementing is probably to:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- Implement a dedicated 'termination' personality function (in compiler-rt?) that does appropriate logging + exit.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- Add a flag (-fterminate-exceptions?). This is because this is a very clear behavior change, so at least providing an opt-in/opt-out mechanism seems important. Possible option: make this an enum, have 'strict' = all exceptions crash, 'normal'
= exceptions passing through methods that would require a cleanup /etc. terminate, none (default) = current behavior where things just leak/etc.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- During code generation, when -fno-exceptions is turned on, if -fterminate-exceptions was passed, it changes the personality function from being not-present to being the dedicated -fno-exceptions termination personality function.
<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">Not sure how much binary size balances with other concerns, but it sounds to me that the methods proposed are ones that would result in false positives where unwinding through the frame would have resulted in no action even when compiled
with exceptions fully on.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">Perhaps leaving functions that would otherwise be "transparent" to exception handling alone is already implied?<o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">So I think this is actually not ideal behavior, at least for the use case I have in mind.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I think I'd prefer (and the team I partner with would prefer) /any/ exception passing from code compiled with -fexceptions to code compiled with -fno-exceptions to halt & return an error, even if the method wouldn't have participated in
exception handling (e.x. no classes that need to have destructors called, etc.) I think the most desirable behavior is "the program halts if exceptions pass through code compiled without exceptions enabled".<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">There's a few reasons for this:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">First, because you can imagine that you could wind up with a situation where a "happy path" will usually work (but then you get an unexpected halt on a less well tested path).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Second, because you can imagine a situation where that winds up putting code in a very weird position where adding a local variable with a destructor that must be called changes how a particular method participates in exception handling
from "it just passes exceptions through" to "it crashes". This could leave code in a weird state where it's hard to reason about the impact of a change or it goes from a perceived "working fine" state to a crashing state.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Third, it makes using *SAN code harder and less predictable. The reason I became aware of this issue at all is that various sanitizers will insert landing pads to keep track of stack unwinding (but don't do that with -fno-exceptions code
or if they believe an exception cannot pass through the method). That then leads to very, very weird behavior with those sanitizers (memory leaks, very weird/hard to unravel stacks as new frames get consistently added, etc.). Sure--you could make the *SAN
build terminate in that case instead of just behaving weirdly, but it'd be nice to get that behavior for normal code (since it's unrelated to the *SAN behavior).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If having an intermediate scenario makes sense (only halting when a method would have taken part in exception handling), then making the flag have 3 states (strict/normal/none) seems like the right choice to me.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thoughts/feedback on this approach?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I have verified that changing the personality function to std::terminate during code generation (via a boolean flag/etc.) does exactly what I'm looking for (but also has an impact on intermediate sizes of about what I expected).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">--EJM<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Tue, Dec 8, 2020 at 10:05 AM Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Mon, Dec 7, 2020 at 3:31 PM Modi Mo via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Modi<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> on behalf of Everett Maus via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Reply-To: </b>Everett Maus <<a href="mailto:evmaus@google.com" target="_blank">evmaus@google.com</a>><br>
<b>Date: </b>Monday, December 7, 2020 at 12:47 PM<br>
<b>To: </b>"<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>" <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject: </b>[llvm-dev] Catching exceptions while unwinding through -fno-exceptions code</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hey all:<o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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 <a href="https://lists.llvm.org/pipermail/llvm-dev/2017-February/109992.html" target="_blank">https://lists.llvm.org/pipermail/llvm-dev/2017-February/109992.html</a>
and <a href="https://lists.llvm.org/pipermail/llvm-dev/2017-February/109995.html" target="_blank">https://lists.llvm.org/pipermail/llvm-dev/2017-February/109995.html</a>)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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?)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Thanks,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">--
<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">--EJM<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><o:p></o:p></p>
</blockquote>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal">-- <o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">--EJM<o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br clear="all">
<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal">-- <o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">--EJM<o:p></o:p></p>
</div>
</div>
</div>
</body>
</html>