[Boost-bugs] [Boost C++ Libraries] #9437: [PATCH] Unable to catch exceptions on iOS and Windows Phone 8

Subject: [Boost-bugs] [Boost C++ Libraries] #9437: [PATCH] Unable to catch exceptions on iOS and Windows Phone 8
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-11-26 17:12:32


#9437: [PATCH] Unable to catch exceptions on iOS and Windows Phone 8
-----------------------------------------------+---------------------
 Reporter: Evgeny Shapovalov <johncapfull@…> | Owner: olli
     Type: Patches | Status: new
Milestone: To Be Determined | Component: context
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
-----------------------------------------------+---------------------
 '''Abstract'''
 1. jump_arm_aapcs_pe_armasm.asm fails to compile using armasm from MSVS
 2012 with error A2193: "This instruction generates unpredictable
 behavior";
 2. Throwing an exception inside custom context leads to crash with
 "Unhandled exception ..." error despite of try/catch block under Windows
 Phone 8;
 3. Same as above, but not stable to reproduce for iOS.

 Attached patch for current boost trunk will fix all issues descrbed above.

 '''Rationale'''
 1. Armasm assembling fails on following instruction

 {{{
 stmia a1, {r4-r11,sp-lr}

 }}}
 This occurs because

 ''"In the Microsoft ARM assembler, THUMB indicates that a CODE section
 contains Thumb code, and is the default for CODE sections"''
 http:msdn.microsoft.com/en-us/library/vstudio/hh916385.aspx

 AFAIK in THUMB mode stmia/ldmia cannot be done for SP and PC.

 Fix: To be able to compile in both ARM and THUMB mode, SP register can be
 saved separately as following:

 {{{
     stmia a1, {r4-r11,lr} ; save V1-V8,LR
     str sp, [a1,#0x24] ; save SP separately

 }}}
 The same is done for ldmia. Note that I reordered SP and LR to avoid
 saving LR separately.

 2. In Windows Phohe 8 throwing an exception leads to crash in all cases.
 It seems that Windows use current StackBase and StackLimit 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.

 Fix: Similar to x86_64. Get TIB inside jump_fcontext and save/load
 StackBase and StackLimit for current thread. Do not need to modify
 fcontext structure because StackLimit can be easily calculated from stack
 base and size.

 3. 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.

 And,
 ''"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."''
 https:www.opensource.apple.com/source/libunwind/libunwind-35.3/src/Unwind-
 sjlj.c
 http:llvm.org/docs/ExceptionHandling.html#setjmp-longjmp-exception-
 handling

 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.


 '''Sample code (how to reproduce for both WP8 and iOS)'''
 {{{
     void routine(intptr_t) {
         try {
             ctx::jump_fcontext(fc, &fcm, 0);
             throw std::exception(); // Unhandled exception crash here
         } catch(std::exception) {
             std::cout << "exception caught" << std::endl;
         }
         ctx::jump_fcontext(fc, &fcm, 0);
     }

     int main() {
         // allocate context here...

         try {
             ctx::jump_fcontext(&fcm, fc, 0);
         } catch (...) {
         }
         ctx::jump_fcontext(&fcm, fc, 0);
     }
 }}}

 PS. Sorry for links, I was unable to pass anti-spam check without changing
 them.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9437>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:14 UTC