| 277 | } |
| 278 | |
| 279 | static _Unwind_Reason_Code |
| 280 | unwind_phase2_forced(unw_context_t *uc, |
| 281 | _Unwind_Exception *exception_object, |
| 282 | _Unwind_Stop_Fn stop, void *stop_parameter) { |
| 283 | unw_cursor_t cursor2; |
| 284 | __unw_init_local(&cursor2, uc); |
| 285 | |
| 286 | // Walk each frame until we reach where search phase said to stop |
| 287 | while (__unw_step(&cursor2) > 0) { |
| 288 | |
| 289 | // Update info about this frame. |
| 290 | unw_proc_info_t frameInfo; |
| 291 | if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { |
| 292 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info " |
| 293 | "failed => _URC_END_OF_STACK", |
| 294 | (void *)exception_object); |
| 295 | return _URC_FATAL_PHASE2_ERROR; |
| 296 | } |
| 297 | |
| 298 | #ifndef NDEBUG |
| 299 | // When tracing, print state information. |
| 300 | if (_LIBUNWIND_TRACING_UNWINDING) { |
| 301 | char functionBuf[512]; |
| 302 | const char *functionName = functionBuf; |
| 303 | unw_word_t offset; |
| 304 | if ((__unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf), |
| 305 | &offset) != UNW_ESUCCESS) || |
| 306 | (frameInfo.start_ip + offset > frameInfo.end_ip)) |
| 307 | functionName = ".anonymous."; |
| 308 | _LIBUNWIND_TRACE_UNWINDING( |
| 309 | "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR |
| 310 | ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, |
| 311 | (void *)exception_object, frameInfo.start_ip, functionName, |
| 312 | frameInfo.lsda, frameInfo.handler); |
| 313 | } |
| 314 | #endif |
| 315 | |
| 316 | // Call stop function at each frame. |
| 317 | _Unwind_Action action = |
| 318 | (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); |
| 319 | _Unwind_Reason_Code stopResult = |
| 320 | (*stop)(1, action, exception_object->exception_class, exception_object, |
| 321 | (struct _Unwind_Context *)(&cursor2), stop_parameter); |
| 322 | _LIBUNWIND_TRACE_UNWINDING( |
| 323 | "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", |
| 324 | (void *)exception_object, stopResult); |
| 325 | if (stopResult != _URC_NO_REASON) { |
| 326 | _LIBUNWIND_TRACE_UNWINDING( |
| 327 | "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", |
| 328 | (void *)exception_object); |
| 329 | return _URC_FATAL_PHASE2_ERROR; |
| 330 | } |
| 331 | |
| 332 | // If there is a personality routine, tell it we are unwinding. |
| 333 | if (frameInfo.handler != 0) { |
| 334 | _Unwind_Personality_Fn p = |
| 335 | (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); |
| 336 | _LIBUNWIND_TRACE_UNWINDING( |
no test coverage detected