Changes in libcfa/src/exception.c [eb46fdf:d43ed2c]
- File:
-
- 1 edited
-
libcfa/src/exception.c (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
reb46fdf rd43ed2c 69 69 70 70 71 // This macro should be the only thing that needs to change across machines. 72 // Used in the personality function, way downin termination.71 // This macro should be the only thing that needs to change across machines. Used in the personality function, way down 72 // in termination. 73 73 // struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception_t *) 74 74 #define MATCHER_FROM_CONTEXT(ptr_to_context) \ … … 102 102 } 103 103 104 // Do we control where exceptions get thrown even with concurency? 105 // If not these are not quite thread safe, the cleanup hook has to 106 // be added after the node is built but before it is made the top node. 104 // Do we control where exceptions get thrown even with concurency? If not these are not quite thread safe, the cleanup 105 // hook has to be added after the node is built but before it is made the top node. 107 106 108 107 void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node, … … 213 212 _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage ); 214 213 215 // If we reach here it means something happened. For resumption to work we need to find a way 216 // to return back to here. Most of them will probably boil down to setting a global flag and 217 // making the phase 1 either stop or fail. Causing an error on purpose may help avoiding 218 // unnecessary work but it might have some weird side effects. If we just pretend no handler 219 // was found that would work but may be expensive for no reason since we will always search 220 // the whole stack. 214 // If we reach here it means something happened. For resumption to work we need to find a way to return back to 215 // here. Most of them will probably boil down to setting a global flag and making the phase 1 either stop or 216 // fail. Causing an error on purpose may help avoiding unnecessary work but it might have some weird side 217 // effects. If we just pretend no handler was found that would work but may be expensive for no reason since we 218 // will always search the whole stack. 221 219 222 220 if( ret == _URC_END_OF_STACK ) { 223 // No proper handler was found. This can be handled in many ways, C++ calls std::terminate.224 // Here weforce unwind the stack, basically raising a cancellation.221 // No proper handler was found. This can be handled in several way. C++ calls std::terminate Here we 222 // force unwind the stack, basically raising a cancellation. 225 223 printf("Uncaught exception %p\n", &this_exception_storage); 226 224 … … 230 228 } 231 229 232 // We did not simply reach the end of the stack without finding a handler. This is an error.230 // We did not simply reach the end of the stack without finding a handler. Something wen't wrong 233 231 printf("UNWIND ERROR %d after raise exception\n", ret); 234 232 abort(); … … 256 254 abort(); 257 255 } 258 #else // PIC 259 // This is our personality routine. For every stack frame annotated with 260 // ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding. 261 // Once in the search phase and once in the cleanup phase. 256 #else 257 // This is our personality routine. For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0". 258 // This function will be called twice when unwinding. Once in the search phased and once in the cleanup phase. 262 259 _Unwind_Reason_Code __gcfa_personality_v0 ( 263 260 int version, _Unwind_Action actions, unsigned long long exceptionClass, … … 267 264 268 265 //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context)); 269 __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", 270 version, actions, exceptionClass, unwind_exception, context); 266 __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context); 271 267 272 268 // If we've reached the end of the stack then there is nothing much we can do... … … 295 291 // Get the instuction pointer and a reading pointer into the exception table 296 292 lsda_header_info lsd_info; 297 const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);293 const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info); 298 294 _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context ); 299 295 … … 306 302 307 303 // Decode the common stuff we have in here 308 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);309 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);310 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);311 cur_ptr = read_uleb128 (cur_ptr, &callsite_action);304 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start); 305 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len); 306 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad); 307 cur_ptr = read_uleb128 (cur_ptr, &callsite_action); 312 308 313 309 // Have we reach the correct frame info yet? … … 320 316 void * ep = (void*)lsd_info.Start + callsite_start + callsite_len; 321 317 void * ip = (void*)instruction_ptr; 322 __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", 323 bp, ep, ls, cs, cl, ip); 318 __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip); 324 319 #endif // __CFA_DEBUG_PRINT__ 325 320 continue; 326 321 } 327 322 328 // Have we gone too far ?323 // Have we gone too far 329 324 if( lsd_info.Start + callsite_start > instruction_ptr ) { 330 325 printf(" gone too far"); … … 336 331 // Which phase are we in 337 332 if (actions & _UA_SEARCH_PHASE) { 338 // In search phase, these means we found a potential handler we must check.339 340 // We have arbitrarily decided that 0 means nothing to do and 1 means there is341 // a potential handler. This doesn't seem to conflict the gcc default behavior.333 // Search phase, this means we probably found a potential handler and must check if it is a match 334 335 // If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler 336 // This doesn't seem to conflict the gcc default behavior 342 337 if (callsite_action != 0) { 343 338 // Now we want to run some code to see if the handler matches … … 356 351 // The current apprach uses one exception table entry per try block 357 352 _uleb128_t imatcher; 358 // Get the relative offset to the {...}? 359 cur_ptr = read_uleb128(cur_ptr, &imatcher); 353 // Get the relative offset to the 354 cur_ptr = read_uleb128 (cur_ptr, &imatcher); 355 356 // Get a function pointer from the relative offset and call it 357 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 360 358 361 359 _Unwind_Reason_Code (*matcher)(exception_t *) = … … 416 414 } 417 415 418 // Try statements are hoisted out see comments for details. While this could probably be unique419 // and simply linked fromlibcfa but there is one problem left, see the exception table for details416 // Try statements are hoisted out see comments for details. With this could probably be unique and simply linked from 417 // libcfa but there is one problem left, see the exception table for details 420 418 __attribute__((noinline)) 421 419 void __cfaabi_ehm__try_terminate(void (*try_block)(), … … 430 428 // assembly works. 431 429 432 // Setup the personality routine and exception table.430 // Setup the personality routine 433 431 asm volatile (".cfi_personality 0x3,__gcfa_personality_v0"); 432 // Setup the exception table 434 433 asm volatile (".cfi_lsda 0x3, .LLSDACFA2"); 435 434 … … 443 442 asm volatile goto ("" : : : : CATCH ); 444 443 445 // Normal return for when there is no throw.444 // Normal return 446 445 return; 447 446 … … 460 459 } 461 460 462 // Exception table data we need to generate. While this is almost generic, the custom data refers 463 // to {*}try_terminate, which is no way generic. Some more works need to be done if we want to 464 // have a single call to the try routine. 461 // Exception table data we need to generate. While this is almost generic, the custom data refers to foo_try_match try 462 // match, which is no way generic. Some more works need to be done if we want to have a single call to the try routine. 465 463 466 464 #if defined( __i386 ) || defined( __x86_64 ) 467 465 asm ( 468 // HEADER466 //HEADER 469 467 ".LFECFA1:\n" 470 468 " .globl __gcfa_personality_v0\n" 471 469 " .section .gcc_except_table,\"a\",@progbits\n" 472 // TABLE HEADER (important field is the BODY length at the end) 473 ".LLSDACFA2:\n" 470 ".LLSDACFA2:\n" //TABLE header 474 471 " .byte 0xff\n" 475 472 " .byte 0xff\n" 476 473 " .byte 0x1\n" 477 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" 478 // BODY (language specific data) 479 ".LLSDACSBCFA2:\n" 480 // Handled area start (relative to start of function) 481 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" 482 // Handled area length 483 " .uleb128 .TRYEND-.TRYSTART\n" 484 // Handler landing pad address (relative to start of function) 485 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" 486 // Action code, gcc seems to always use 0. 487 " .uleb128 1\n" 488 // TABLE FOOTER 489 ".LLSDACSECFA2:\n" 490 " .text\n" 474 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" // BODY length 475 // Body uses language specific data and therefore could be modified arbitrarily 476 ".LLSDACSBCFA2:\n" // BODY start 477 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" // Handled area start (relative to start of function) 478 " .uleb128 .TRYEND-.TRYSTART\n" // Handled area length 479 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" // Hanlder landing pad adress (relative to start of function) 480 " .uleb128 1\n" // Action code, gcc seems to use always 0 481 ".LLSDACSECFA2:\n" // BODY end 482 " .text\n" // TABLE footer 491 483 " .size __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n" 492 484 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n" … … 494 486 ); 495 487 #endif // __i386 || __x86_64 496 #endif // PIC488 #endif //PIC
Note:
See TracChangeset
for help on using the changeset viewer.