Opened 9 years ago
Closed 9 years ago
#9437 closed Patches (fixed)
[PATCH] Unable to catch exceptions on iOS and Windows Phone 8
Reported by: | Owned by: | olli | |
---|---|---|---|
Milestone: | To Be Determined | Component: | context |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: |
Description
Abstract
- jump_arm_aapcs_pe_armasm.asm fails to compile using armasm from MSVS 2012 with error A2193: "This instruction generates unpredictable behavior";
- Throwing an exception inside custom context leads to crash with "Unhandled exception ..." error despite of try/catch block under Windows Phone 8;
- Same as above, but not stable to reproduce for iOS.
Attached patch for current boost trunk will fix all issues descrbed above.
Rationale
- 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.
- 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.
- 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.
Attachments (2)
Change History (8)
by , 9 years ago
Attachment: | boost-trunk-context-throw-wp8-ios.patch added |
---|
by , 9 years ago
Attachment: | how-to-reproduce.cpp added |
---|
Full source code to reproduce described issues
comment:1 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
1.) ABI used by IOS is different from AAPCS + IOS is not supported (yet). 2.) Windows on ARM is not supported
follow-up: 3 comment:2 by , 9 years ago
ABI used by IOS is different from AAPCS
Exactly
IOS is not supported
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.
jump_arm_aapcs_pe_armasm.asm jump_arm_aapcs_macho_gas.S
The only useful platforms for them are WP and iOS. AFAIK.
comment:3 by , 9 years ago
Replying to Evgeny Shapovalov <johncapfull@…>:
IOS is not supported
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.
I'm working on iOS port but I've not enough time.
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 (http://msdn.microsoft.com/en-us/library/aa448751.aspx).
comment:4 by , 9 years ago
To enable SEH on ARM it requires PDATA structure for the functions in the asm-files in order to set up the exception handlers
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.
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.
See description and patch attached as proposed way to fix this.
comment:5 by , 9 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
comment:6 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
patch with fixes