id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 9437,[PATCH] Unable to catch exceptions on iOS and Windows Phone 8,Evgeny Shapovalov ,olli,"'''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.",Patches,closed,To Be Determined,context,Boost Development Trunk,Problem,fixed,,