[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #11 from Mark Millard --- (In reply to Mark Millard from comment #10) Testing with a build based on head -r339076 shows this still happens. Both clang code generation and devel/powerpc64-xtoolchain-gcc code generation have examples of hitting the mishandling in libgcc_s.so and so __Unwind_RaiseException looping on the same stack frame over and over. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #10 from Mark Millard--- Here is what dwarf-2.0.0.pdf says about DW_CFA_remember_state and DW_CFA_restore_state: 13. DW_CFA_remember_state 14. DW_CFA_restore_state These instructions define a stack of information. Encountering the DW_CFA_remember_state instruction means to save the rules for every register on the current row on the stack. Encountering the DW_CFA_restore_state instruction means to pop the set of rules off the stack and place them in the current row. (This operation is useful for compilers that move epilogue code into the body of a function.) The correct interpretation of "save the rules for every register on the current row on the stack" is to include the cfa "register" as one of those registers that has its rules saved: it is not just processor registers that are to be saved and restored but also the logical one(s). dwarf-2.0.0.pdf also says: • The algorithm to compute the CFA changes as you progress through the prologue and epilogue code. (By definition, the CFA value does not change.) So technically the "rules" material for the cfa "Register" need not include the cfa value on the stack. (But pushing and popping what stays a constant value is still correct.) Also the cfa register is somewhat special by only having special instructions: 15. DW_CFA_def_cfa takes two unsigned LEB128 arguments representing a register number and an offset. The required action is to define the current CFA rule to use the provided register and offset. 16. DW_CFA_def_cfa_register takes a single unsigned LEB128 argument representing a register number. The required action is to define the current CFA rule to use the provided register (but to keep the old offset). 17. DW_CFA_def_cfa_offset takes a single unsigned LEB128 argument representing an offset. The required action is to define the current CFA rule to use the provided offset (but to keep the old register). These only allow the resulting cfa definition rules to be of the form: cfa=OFFSET(REG). -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #9 from Mark Millard--- A find over /usr/src/ with egrep use suggests that the later files listed are files that use the cfa fields. They match the pattern: [.>]cfa_(offset|reg|exp|how) /usr/src/contrib/gcc/config/mips/linux-unwind.h /usr/src/contrib/gcc/config/rs6000/linux-unwind.h /usr/src/contrib/gcc/config/rs6000/darwin-fallback.c /usr/src/contrib/gcc/config/i386/linux-unwind.h /usr/src/contrib/gcc/config/sparc/linux-unwind.h /usr/src/contrib/gcc/config/s390/tpf-unwind.h /usr/src/contrib/gcc/config/s390/linux-unwind.h /usr/src/contrib/gcc/unwind-dw2.c /usr/src/contrib/gcc/dwarf2out.c /usr/src/contrib/gdb/gdb/dwarf2-frame.c /usr/src/contrib/binutils/gas/dw2gencfi.c /usr/src/contrib/binutils/binutils/dwarf.c And _Unwind_FrameState is mentioned in each of: /usr/src/contrib/gcc/config/mips/linux-unwind.h /usr/src/contrib/gcc/config/rs6000/linux-unwind.h /usr/src/contrib/gcc/config/rs6000/darwin-fallback.c /usr/src/contrib/gcc/config/rs6000/darwin-unwind.h /usr/src/contrib/gcc/config/i386/linux-unwind.h /usr/src/contrib/gcc/config/sparc/linux-unwind.h /usr/src/contrib/gcc/config/s390/tpf-unwind.h /usr/src/contrib/gcc/config/s390/linux-unwind.h /usr/src/contrib/gcc/config/ia64/unwind-ia64.c /usr/src/contrib/gcc/config/ia64/linux-unwind.h /usr/src/contrib/gcc/doc/tm.texi /usr/src/contrib/gcc/unwind-sjlj.c /usr/src/contrib/gcc/ChangeLog-2006 /usr/src/contrib/gcc/ChangeLog-2001 /usr/src/contrib/gcc/unwind.inc /usr/src/contrib/gcc/unwind-dw2.h /usr/src/contrib/gcc/unwind-dw2.c /usr/src/contrib/gcc/ChangeLog-2004 /usr/src/contrib/gcc/ChangeLog-2003 That in turn suggests that they are most(?) of the files that would be tied to any attempt to have DW_CFA_remember_state/DW_CFA_restore_state save and restore the cfa information. One possibility is moving the fields into the saved/restored area (regs, along with the contained fields prev and reg). Access notation would then be based on: ->regs.cfa_offset and .regs.cfa_offset ->regs.cfa_reg and .regs.cfa_reg ->regs.cfa_exp and .regs.cfa_exp ->regs.cfa_how and .regs.cfa_how -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #8 from Mark Millard--- A warning relative to clang 3.8.0 and c++ exception handling and being able to test fixes to c++ exception handling in an overall manor for clang: clang 3.8.0 for powerpc and powerpc64 messes up what __builtin_dwarf_cfa() returns and the c++ exception handling infrastructure depends on that. So until both clang 3.8.0's __builtin_dwarf_cfa() and the FreeBSD's libgcc_s's DW_CFA_remember_state/DW_CFA_restore_state handling are fixed c++ exceptions are going to be broken to some degree. (The clang problem is always involved.) powerpc64's use of a stack "red zone" and late stack pointer decrementing/early incrementing may make it more likely to use DW_CFA_remember_state/DW_CFA_restore_state in the .eh_frame information, especially with inlining and the llike. Currently clang 3.8.0's ABI violation for powerpc code generation puts it in the same category with powerpc64 for this since it is also using a "red zone". g++49 and g++5 do not have clang's __builtin_dwarf_cfa() problem for powerpc64 or for powerpc. So for now they are better for having a more overall testing of library code involved in C++ exception handling. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #7 from Mark Millard--- (In reply to Mark Millard from comment #6) I have verified that dwarfdump and its libdwarf do save and restore the following for the cfa for DW_CFA_remember_state/DW_CFA_restore_state: A) Of the offset is relevant or not (if it has a offset style rule) B) the rule-value type C) the register number that the cfa is based on D) the offset or block length by naming conventions E) the block pointer I do not claim that all that applies to the mostly dwarf2 FreeBSD context. But I expect that (A)-(D) apply, (D) just for the offset case. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #6 from Mark Millard--- (In reply to Mark Millard from comment #5) The uw_update_context_1 material would have been clearler if I'd listed another line from the source code. So I do below. fs->cfa_offset is not part of regs but is later used by uw_update_context_1 for: /* Compute this frame's CFA. */ switch (fs->cfa_how) { case CFA_REG_OFFSET: cfa = _Unwind_GetPtr (_context, fs->cfa_reg); cfa += fs->cfa_offset; break; . . . context->cfa = cfa; That last explains how the fs->cfa_offset is supposed to end up involved in later activity. (fs is local to each loop iteration; context's lifetime spans across iterations.) Also: I see that in at least one place I typed "12" instead of "128". Be warned. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #5 from Mark Millard--- (In reply to Mark Millard from comment #4) A new, corrected, even lower level detail interpretation. . . which may put the burden on the system's .eh_frame handling in libgcc_s. I state the relationship from the point of view what the existing fde operations would need to do to be correct. The alternate is that the missing activity is missing operations instead of the activity being "inside" DW_CFA_remember_state and DW_CFA_restore_state. The problem is that the DW_CFA_remember_state and later DW_CFA_restore_state do not in fact restore the cfa_offset (in this case 128 as it was at the time of the DW_CFA_remember_state). dwarfdump shows in its notation that the DW_CFA_restore_state should restore the "off cfa=128(r1)" status. This makes sense for the code in question. But DW_CFA_remember_state/DW_CFA_restore_state do not save and restore the cfa_offset (12 here). DW_CFA_remember_state only saves fs->regs. DW_CFA_restore_state only restores fs->regs. fs->cfa_offset is not part of regs but is used by uw_update_context_1 for: /* Compute this frame's CFA. */ switch (fs->cfa_how) { case CFA_REG_OFFSET: cfa = _Unwind_GetPtr (_context, fs->cfa_reg); cfa += fs->cfa_offset; break; In the example fs->cfa_offset ends up being 0 instead of 128 after the DW_CFA_restore_state, causing the wrong frame's return address to be used. For reference: The below is the dwarfdump -v -v -F for throw_exception (where the "stuck" return address vale problem [0x000153a0] is observed): <0><0x00015310:0x000153dc> 0x00015310: 0x00015318: 0x00015324: 0x00015368: 0x00015378: 0x00015380: 0x000153a8: 0x000153b8: 0x000153c0: fde section offset 4312 0x10d8 cie offset for fde: 4316 0x10dc 0 DW_CFA_advance_loc 8 (2 * 4) 1 DW_CFA_register r65 = r0 4 DW_CFA_offset r31 -8 (1 * -8) 6 DW_CFA_advance_loc 12 (3 * 4) 7 DW_CFA_def_cfa_offset 128 10 DW_CFA_offset_extended_sf r65 16 (-2 * -8) 13 DW_CFA_advance_loc 68 (17 * 4) 14 DW_CFA_remember_state 15 DW_CFA_def_cfa_offset 0 17 DW_CFA_advance_loc 16 (4 * 4) 18 DW_CFA_restore_extended r65 20 DW_CFA_restore r31 21 DW_CFA_advance_loc 8 (2 * 4) 22 DW_CFA_restore_state 23 DW_CFA_advance_loc 40 (10 * 4) 24 DW_CFA_remember_state 25 DW_CFA_def_cfa_offset 0 27 DW_CFA_advance_loc 16 (4 * 4) 28 DW_CFA_restore_extended r65 30 DW_CFA_restore r31 31 DW_CFA_advance_loc 8 (2 * 4) 32 DW_CFA_restore_state 33 DW_CFA_nop 34 DW_CFA_nop 35 DW_CFA_nop 36 DW_CFA_nop 37 DW_CFA_nop 38 DW_CFA_nop Note that if fs->cfa_reg could be varying then DW_CFA_remember_state and DW_CFA_restore_state would need to do appropriate save/restore activity for that too. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #4 from Mark Millard--- (In reply to Mark Millard from comment #3) And now I see that I types "libc++" in places that I should have typed "libcxxrt". Noted here just to help avoid confusions. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #3 from Mark Millard--- (In reply to Mark Millard from comment #2) I should have noted that powerpc64-gcc was used for buildworld of projects/clang380-import -r295902 (and other versions) --and so for libcxxrt as well. It is g++ 5.3 that put out the incomplete .eh_frame frame-context tracking. -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 --- Comment #2 from Mark Millard--- I've finally traced the low level details of the _Unwind_RaiseException stuck looping failure. . . Starting from the observed low-level evidence based on observation via gdb and such: A backtrace while stopped during the unbounded looping is: #0 uw_update_context (context=context@entry=0xccf0, fs=fs@entry=0xc370) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1371 #1 0x501cb95c in _Unwind_RaiseException (exc=0x50815058) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:126 #2 0x5016e3a0 in throw_exception (ex=0x50815000) at /usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:751 #3 0x1d50 in main () at exception_test.cpp:5 _Unwind_RaiseException never returns for source code that looks like: #include int main(void) { try { throw std::exception(); } catch (std::exception& e) {} return 0; } where in /usr/lib/libc++.so.1 there is: 736 static void throw_exception(__cxa_exception *ex) 737 { . . . 751 _Unwind_Reason_Code err = _Unwind_RaiseException(>unwindHeader); . . . 756 } The unbounded loop in _Unwind_RaiseException is in the code: 85 _Unwind_Reason_Code 86 _Unwind_RaiseException(struct _Unwind_Exception *exc) 87 { 88struct _Unwind_Context this_context, cur_context; 89_Unwind_Reason_Code code; 90 91/* Set up this_context to describe the current stack frame. */ 92uw_init_context (_context); 93cur_context = this_context; 94 95/* Phase 1: Search. Unwind the stack, calling the personality routine 96 with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */ 97while (1) 98 { 99_Unwind_FrameState fs; 100 101 /* Set up fs to describe the FDE for the caller of cur_context. The 102 first time through the loop, that means __cxa_throw. */ 103 code = uw_frame_state_for (_context, ); . . . 125 /* Update cur_context to describe the same frame as fs. */ 126 uw_update_context (_context, ); 127 } . . . 140 } The uw_update_context call is doing the following before returning: 1367 /* Compute the return address now, since the return address column 1368 can change from frame to frame. */ 1369 context->ra = __builtin_extract_return_addr 1370(_Unwind_GetPtr (context, fs->retaddr_column)); with context->ra before and after the call both being 0x5016e3a0 . In fact it was 0x5016e3a0 for the prior uw_frame_state_for call as well and continues to be so each loop iteration once the problem starts. As for the code around 0x5016e3a0: 0x5016e398 : stw r10,48(r9) 0x5016e39c : bl 0x50162ae0 <0017.plt_call._Unwind_RaiseException@@GCC_3.0> 0x5016e3a0 : ld r2,40(r1) 0x5016e3a4 : addi r1,r1,128 0x5016e3a8 : mr r4,r31 0x5016e3ac : ld r0,16(r1) From /usr/local/bin/objdump for FreeBSD projects/clang380-import -r295902's /usr/lib/libc++.so.1 for the same code (to match up with the .eh_frame dwarf information presented later): 00015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9) 0001539c <.__cxa_end_catch+0x4dc> bl 9ae0 000153a0 <.__cxa_end_catch+0x4e0> ld r2,40(r1) 000153a4 <.__cxa_end_catch+0x4e4> addir1,r1,128 000153a8 <.__cxa_end_catch+0x4e8> mr r4,r31 000153ac <.__cxa_end_catch+0x4ec> ld r0,16(r1) The code block above from 153a0 up to 153a8 is being given 153a0 as its "return address" (context->ra) by uw_update_context via interpreting the dwarf .eh_frame information. So once in that range there it never leaves that range. The relevant dwarfdump output spanning that area is: (Note that 153a0 up to 153a8 is part of the range that includes the bl to _Unwind_RaiseException .) <0><0x00015310:0x000153dc><> 0x00015310: 0x00015318: 0x00015324: 0x00015368: 0x00015378: 0x00015380: 0x000153a8: 0x000153b8: 0x000153c0: fde section offset 4312 0x10d8 cie offset for fde: 4316 0x10dc 0 DW_CFA_advance_loc 8 (2 * 4) 1 DW_CFA_register r65 = r0 4 DW_CFA_offset r31 -8 (1 * -8) 6 DW_CFA_advance_loc 12 (3 * 4) 7 DW_CFA_def_cfa_offset 128 10 DW_CFA_offset_extended_sf r65 16 (-2 * -8) 13 DW_CFA_advance_loc 68 (17 * 4) 14
[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359 Bug ID: 207359 Summary: projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program) Product: Base System Version: 11.0-CURRENT Hardware: ppc OS: Any Status: New Severity: Affects Only Me Priority: --- Component: bin Assignee: freebsd-bugs@FreeBSD.org Reporter: mar...@dsl-only.net >From a buildworld/buildkernel install for TARGET_ARCH=powerpc64 based on powerpc64-xtoolchain-gcc/powerpc64-gcc form projects/clang380-import -r205601. . . #include int main(void) { try { throw std::exception(); } catch (std::exception& e) {} // same result without & return 0; } (This simplifies what I found in trying to use "kyua test -k /usr/tests/Kyuafile", which does not progress but uses 100% of a cpu/oore.) # g++ --version g++ (FreeBSD Ports Collection for powerpc64) 5.3.0 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # g++ -I /usr/include/c++/v1/ -L /usr/lib/ -g -Wall -pedantic exception_test.cpp ./a.out never finishes. from gdb: Program received signal SIGINT, Interrupt. 0x5002a088 in .__sys_sigprocmask () from /libexec/ld-elf.so.1 (gdb) bt #0 0x5002a088 in .__sys_sigprocmask () from /libexec/ld-elf.so.1 #1 0x50029c1c in sigprocmask (how=0, set=0x500493a4 , oset=0x0) at /usr/src/lib/libc/sys/sigprocmask.c:48 #2 0x50022d98 in def_lock_release (lock=) at /usr/src/libexec/rtld-elf/rtld_lock.c:141 #3 0x50023028 in lock_release (lock=0x500496a8, lockstate=) at /usr/src/libexec/rtld-elf/rtld_lock.c:234 #4 0x5001ddac in dl_iterate_phdr (callback=@0x501e1b50: 0x501ce350 <_Unwind_IteratePhdrCallback>, param=0xc210) at /usr/src/libexec/rtld-elf/rtld.c:3544 #5 0x501cf33c in _Unwind_Find_FDE (pc=0x5016e39f , bases=0xd1d8) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2-fde-glibc.c:420 #6 0x501ca9e0 in uw_frame_state_for (context=context@entry=0xcd30, fs=fs@entry=0xc3b0) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1106 #7 0x501cb968 in _Unwind_RaiseException (exc=0x50815058) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:103 #8 0x5016e3a0 in throw_exception (ex=0x50815000) at /usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:751 #9 0x1d50 in main () at exception_test.cpp:5 . . . repeated finish commands until . . . (gdb) finish Run till exit from #0 _Unwind_RaiseException (exc=0x50815058) at /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:117 ^C Program received signal SIGINT, Interrupt. 0x5002a088 in .__sys_sigprocmask () from /libexec/ld-elf.so.1 _Unwind_RaiseException never returns. kyua did the same thing but is a more complicated context. Using g++49's a.out gets the same result for: # g++49 -I /usr/include/c++/v1/ -L /usr/lib/ -g -Wall -pedantic exception_test.cpp But the a.out works fine for: # g++49 -g -Wall -pedantic exception_test.cpp # ./a.out # The difference is the headers/libraries involved. (powerpc64-gcc cannot be used that way: it has a freestanding status and the include path and libraries path need to be supplied.) (clang 3.8.0 is not up to doing a buildworld. For example: it does not support soft float yet, at least last checked. This is part of why I test the provided (ports) cross compile environment for powerpc64 [but in a self-hosted form].) -- You are receiving this mail because: You are the assignee for the bug. ___ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"