<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 3, 2016 at 6:37 PM, Herbie Robinson via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I was curious how std::errc::bad_address was handled; so, I made up this test case (fault_test.cpp):<br></blockquote><div><br></div><div>The std::errc::bad_address code maps to POSIX EFAULT. The intent behind its existence is to inform user code that a system call was passed a bad address. Nowhere in the default stack of software a mechanism to automatically transform faults into exceptions of type 'std::system_error'.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
#include "fault_test.hpp"<br>
#include <exception><br>
#include <system_error><br>
<br>
static int n;<br>
<br>
void fault_test(int *p)<br>
{<br>
std::error_code ec = make_error_code(std::errc::bad_address);<br>
std::system_error e = std::system_error(ec);<br>
<br>
try<br>
{<br>
n += *p;<br>
std::cout << "No fault.\n";<br>
}<br>
catch(const std::system_error &e)<br>
{<br>
std::cout << "Caught the fault.\n";<br>
}<br>
}<br>
<br>
int get_sum(void)<br>
{<br>
return n;<br>
}<br>
<br>
The fault isn't caught by the catch clause, It just faults in the try compound_statement (running it under Xcode). Thinking about this a little bit, I can see why anything implementing unwinding using the GGC algorithm would decline to implement this (because the exception usually wouldn't be handled and that would be pretty rude debug behavior).<br>
<br>
I was wondering if:<br>
<br>
1, The Windows SEH algorithms can handle this?<br></blockquote><div><br></div><div>SEH can handle this with __try/__except but the exception has to be thrown from a call (use noinline on the callsites in the __try block). </div><div><br></div><div>Things get super weird with optimization regardless of inlining (e.g. non volatile loads and stores which commit UB can be removed in call sites inside the try which would result in the __except block not running).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
2. LLVM is prepared to handle exceptions arising out of anything that happens in the try compound statement or only calls?<br>
<br>
The reason I ask is that other OSes that one might port to do support catching general faults in their unwind mechanisms. I believe Multics implemented that in pl1 way back when: The idea is to keep your kernel gates as fast as possible by just making sure output arguments point at things the user is allowed to modify and letting the exception handler catch faults arising from bad reads.<br></blockquote><div><br></div><div>In LLVM, only calls are candidates for throwing. We don't support GCC-style -fnon-call-exceptions.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
The other files for the test:<br>
<br>
fault_test.hpp:<br>
<br>
#include <iostream><br>
<br>
extern void fault_test(int *p);<br>
extern int get_sum(void);<br>
<br>
main.cpp:<br>
<br>
#include "fault_test.hpp"<br>
<br>
int main(int argc, const char * argv[]) {<br>
// insert code here...<br>
fault_test(nullptr);<br>
<br>
std::cout << "Sum = " << get_sum() << "\n";<br>
return 0;<br>
}<br>
<br>
<br>
_______________________________________________<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="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div></div>