https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89228
Bug ID: 89228 Summary: ARM unwinder fails to restore vfp reg $d8 Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libbacktrace Assignee: unassigned at gcc dot gnu.org Reporter: bernd.edlinger at hotmail dot de CC: ian at gcc dot gnu.org Target Milestone: --- This makes gdb enter an endless Loop, which makes the gcc test Suite hang, becaue the gdb process does not terminate, and the Time-out only kills the debuggee. A debug session is in gdb bugzilla at https://sourceware.org/bugzilla/show_bug.cgi?id=24178 It is a bit weird, but I think the reason for this is that __gxx_personality_v0 is saving d8 on the stack, and restores the old d8 on return. 0036f864 <__gxx_personality_v0>: 36f864: e200c003 and ip, r0, #3 36f868: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} 36f86c: e35c0001 cmp ip, #1 36f870: ed2d8b02 vpush {d8} 36f874: e3a03000 mov r3, #0 36f878: e24dd04c sub sp, sp, #76 ; 0x4c 36f87c: e1a07002 mov r7, r2 36f880: e58d100c str r1, [sp, #12] 36f884: e58d3020 str r3, [sp, #32] 36f888: 0a000082 beq 36fa98 <__gxx_personality_v0+0x234> 36f88c: e35c0002 cmp ip, #2 36f890: 1a000008 bne 36f8b8 <__gxx_personality_v0+0x54> 36f894: e59d000c ldr r0, [sp, #12] 36f898: e1a01007 mov r1, r7 36f89c: eb005e60 bl 387224 <__gnu_unwind_frame> 36f8a0: e3500000 cmp r0, #0 36f8a4: 13a00009 movne r0, #9 36f8a8: 03a00008 moveq r0, #8 36f8ac: e28dd04c add sp, sp, #76 ; 0x4c 36f8b0: ecbd8b02 vpop {d8} 36f8b4: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} But __gnu_unwind_frame restores the live vfp registers in violation of the ABI, which would work, if there was a a way to avoid using vfp Registers in the personality function. This function is called from here: static void __attribute__((noreturn)) unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs) { _Unwind_Reason_Code pr_result; do { /* Find the entry for this routine. */ if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK) abort (); UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs); /* Call the pr to decide what to do. */ pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs); } while (pr_result == _URC_CONTINUE_UNWIND); if (pr_result != _URC_INSTALL_CONTEXT) abort(); uw_restore_core_regs (vrs, &vrs->core); } my conclusion so far is: The last uw_restore_core_regs restores only r0..r15, but it should also restore vfp regs on demand. Note that phase2_vrs does not hold enough space for the vfp Registers.