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