Boost C++ Libraries: Ticket #9437: [PATCH] Unable to catch exceptions on iOS and Windows Phone 8 https://svn.boost.org/trac10/ticket/9437 <p> <strong>Abstract</strong> </p> <ol><li>jump_arm_aapcs_pe_armasm.asm fails to compile using armasm from MSVS 2012 with error A2193: "This instruction generates unpredictable behavior"; </li><li>Throwing an exception inside custom context leads to crash with "Unhandled exception ..." error despite of try/catch block under Windows Phone 8; </li><li>Same as above, but not stable to reproduce for iOS. </li></ol><p> Attached patch for current boost trunk will fix all issues descrbed above. </p> <p> <strong>Rationale</strong> </p> <ol><li>Armasm assembling fails on following instruction </li></ol><pre class="wiki">stmia a1, {r4-r11,sp-lr} </pre><p> This occurs because </p> <p> <em>"In the Microsoft ARM assembler, THUMB indicates that a CODE section contains Thumb code, and is the default for CODE sections"</em> http:msdn.microsoft.com/en-us/library/vstudio/hh916385.aspx </p> <p> AFAIK in THUMB mode stmia/ldmia cannot be done for SP and PC. </p> <p> Fix: To be able to compile in both ARM and THUMB mode, SP register can be saved separately as following: </p> <pre class="wiki"> stmia a1, {r4-r11,lr} ; save V1-V8,LR str sp, [a1,#0x24] ; save SP separately </pre><p> The same is done for ldmia. Note that I reordered SP and LR to avoid saving LR separately. </p> <ol start="2"><li>In Windows Phohe 8 throwing an exception leads to crash in all cases. It seems that Windows use current <a class="missing wiki">StackBase</a> and <a class="missing wiki">StackLimit</a> pointers from TIB to locate exception handler for thread. The same should occur for x86_64 under Win32, but it is already handled inside jump_x86_64_ms_pe_masm.asm by saving and loading stack base/limit. </li></ol><p> Fix: Similar to x86_64. Get TIB inside jump_fcontext and save/load <a class="missing wiki">StackBase</a> and <a class="missing wiki">StackLimit</a> for current thread. Do not need to modify fcontext structure because <a class="missing wiki">StackLimit</a> can be easily calculated from stack base and size. </p> <ol start="3"><li>Throwing an exception in iOS crashes application when it is done after switching context back, leaving enclosed try/catch block, and jumping into custom context again. It happens because "ARM uses setjump/longjump based C++ exceptions" in clang. </li></ol><p> And, <em>"With SJLJ based exceptions any function that has a catch clause or needs to do any clean up when an exception propagates through it, needs to call _Unwind_SjLj_Register() at the start of the function and _Unwind_SjLj_Unregister() at the end."</em> https:www.opensource.apple.com/source/libunwind/libunwind-35.3/src/Unwind-sjlj.c http:llvm.org/docs/ExceptionHandling.html#setjmp-longjmp-exception-handling </p> <p> Fix: To locate current exception handler list, libunwind stores top exception handler using pthread_setspecific(PTK_LIBC_DYLD_Unwind_SjLj_Key). So unwind key should be saved/restored at every context switch. Which is done inside jump_arm_aapcs_macho_gas.S. This has required to add additional field inside fcontext_t for ARM under iOS. </p> <p> <strong>Sample code (how to reproduce for both WP8 and iOS)</strong> </p> <pre class="wiki"> void routine(intptr_t) { try { ctx::jump_fcontext(fc, &amp;fcm, 0); throw std::exception(); // Unhandled exception crash here } catch(std::exception) { std::cout &lt;&lt; "exception caught" &lt;&lt; std::endl; } ctx::jump_fcontext(fc, &amp;fcm, 0); } int main() { // allocate context here... try { ctx::jump_fcontext(&amp;fcm, fc, 0); } catch (...) { } ctx::jump_fcontext(&amp;fcm, fc, 0); } </pre><p> PS. Sorry for links, I was unable to pass anti-spam check without changing them. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9437 Trac 1.4.3 Evgeny Shapovalov <johncapfull@…> Tue, 26 Nov 2013 17:13:47 GMT attachment set https://svn.boost.org/trac10/ticket/9437 https://svn.boost.org/trac10/ticket/9437 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost-trunk-context-throw-wp8-ios.patch</span> </li> </ul> <p> patch with fixes </p> Ticket Evgeny Shapovalov <johncapfull@…> Tue, 26 Nov 2013 17:14:36 GMT attachment set https://svn.boost.org/trac10/ticket/9437 https://svn.boost.org/trac10/ticket/9437 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">how-to-reproduce.cpp</span> </li> </ul> <p> Full source code to reproduce described issues </p> Ticket olli Tue, 26 Nov 2013 19:22:41 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9437#comment:1 https://svn.boost.org/trac10/ticket/9437#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> 1.) ABI used by IOS is different from AAPCS + IOS is not supported (yet). 2.) Windows on ARM is not supported </p> Ticket Evgeny Shapovalov <johncapfull@…> Wed, 27 Nov 2013 13:53:20 GMT <link>https://svn.boost.org/trac10/ticket/9437#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9437#comment:2</guid> <description> <blockquote class="citation"> <p> ABI used by IOS is different from AAPCS </p> </blockquote> <p> Exactly </p> <blockquote class="citation"> <p> IOS is not supported </p> </blockquote> <p> Is there any blockers to add support for iOS and Windows on ARM? There are already some ARM stubs in trunk for MACHO and MASM. </p> <pre class="wiki">jump_arm_aapcs_pe_armasm.asm jump_arm_aapcs_macho_gas.S </pre><p> The only useful platforms for them are WP and iOS. AFAIK. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>olli</dc:creator> <pubDate>Wed, 27 Nov 2013 14:31:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9437#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9437#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9437#comment:2" title="Comment 2">Evgeny Shapovalov &lt;johncapfull@…&gt;</a>: </p> <blockquote class="citation"> <blockquote class="citation"> <p> IOS is not supported </p> </blockquote> <p> Is there any blockers to add support for iOS and Windows on ARM? There are already some ARM stubs in trunk for MACHO and MASM. </p> </blockquote> <p> I'm working on iOS port but I've not enough time. </p> <p> The Windows CE/ARM port was reported to work while throwing/catching exceptions will not work. To enable SEH on ARM it requires PDATA structure for the functions in the asm-files in order to set up the exception handlers. MASM has had a special macro for this purpose. The assembler-tool armasm (used for Windows CE/ARM) doesn't. I've to figure out how to setup the PDATA structure (<a class="ext-link" href="http://msdn.microsoft.com/en-us/library/aa448751.aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/aa448751.aspx</a>). </p> </description> <category>Ticket</category> </item> <item> <author>Evgeny Shapovalov <johncapfull@…></author> <pubDate>Wed, 27 Nov 2013 14:45:06 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9437#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9437#comment:4</guid> <description> <blockquote class="citation"> <p> To enable SEH on ARM it requires PDATA structure for the functions in the asm-files in order to set up the exception handlers </p> </blockquote> <p> PDATA in non-throwing function is needed only for unwinding. Since exception cannot be thrown out of context function, there is no need to use pdata in asm. </p> <p> All throwing functions will already have compiler-generated PDATA with associated exception handlers. The reason for non-working exceptions is invalid TEB state in context functions. </p> <p> See description and patch attached as proposed way to fix this. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>olli</dc:creator> <pubDate>Tue, 03 Dec 2013 05:45:14 GMT</pubDate> <title>status changed; resolution deleted https://svn.boost.org/trac10/ticket/9437#comment:5 https://svn.boost.org/trac10/ticket/9437#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> Ticket olli Sun, 15 Dec 2013 09:25:07 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9437#comment:6 https://svn.boost.org/trac10/ticket/9437#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket