[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #16 from Andrew Pinski --- (In reply to AJ D from comment #15) > Is it fixed in GCC-9.4? > > Didn't find PR99334 in > https://gcc.gnu.org/bugzilla/buglist. > cgi?bug_status=RESOLVED=FIXED_milestone=9.4 > > If not, which GCC9.* release can we expect a fix for it? So the target milestone only says the earliest GCC version where it is fixed. I updated the "known to work" field on which release the patch in comment #10, #11, #12, and #13 were committed to. Also updated the target milestone to the correct one.
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 Andrew Pinski changed: What|Removed |Added Known to work||10.3.0, 11.1.0, 8.5.0, ||9.4.0 Target Milestone|8.2 |8.5
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #15 from AJ D --- Is it fixed in GCC-9.4? Didn't find PR99334 in https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED=FIXED_milestone=9.4 If not, which GCC9.* release can we expect a fix for it?
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 Jakub Jelinek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org Status|REOPENED|RESOLVED Resolution|--- |FIXED --- Comment #14 from Jakub Jelinek --- Fixed.
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #13 from CVS Commits --- The releases/gcc-8 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:698b03a66e5115c5dd5cf84bbb499e210df3e709 commit r8-10901-g698b03a66e5115c5dd5cf84bbb499e210df3e709 Author: Jakub Jelinek Date: Sat Mar 27 00:20:42 2021 +0100 dwarf2cfi: Defer queued register saves some more [PR99334] On the testcase in the PR with -fno-tree-sink -O3 -fPIC -fomit-frame-pointer -fno-strict-aliasing -mstackrealign we have prologue: <_func_with_dwarf_issue_>: 0: 4c 8d 54 24 08 lea0x8(%rsp),%r10 5: 48 83 e4 f0 and$0xfff0,%rsp 9: 41 ff 72 f8 pushq -0x8(%r10) d: 55 push %rbp e: 48 89 e5mov%rsp,%rbp 11: 41 57 push %r15 13: 41 56 push %r14 15: 41 55 push %r13 17: 41 54 push %r12 19: 41 52 push %r10 1b: 53 push %rbx 1c: 48 83 ec 20 sub$0x20,%rsp and emit 0014 CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8 DW_CFA_nop DW_CFA_nop 0018 0044 001c FDE cie= pc=..01d5 DW_CFA_advance_loc: 5 to 0005 DW_CFA_def_cfa: r10 (r10) ofs 0 DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 13 to 001b DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8) DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16) DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24) DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32) ... unwind info for that. The problem is when async signal (or stepping through in the debugger) stops after the pushq %rbp instruction and before movq %rsp, %rbp, the unwind info says that caller's %rbp is saved there at *%rbp, but that is not true, caller's %rbp is either still available in the %rbp register, or in *%rsp, only after executing the next instruction - movq %rsp, %rbp - the location for %rbp is correct. So, either we'd need to temporarily say: DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg7 (rsp): 0) DW_CFA_advance_loc: 3 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b or to me it seems more compact to just say: DW_CFA_advance_loc: 12 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b I've tried instead to deal with it through REG_FRAME_RELATED_EXPR from the backend, but that failed miserably as explained in the PR, dwarf2cfi.c has some rules (Rule 16 to Rule 19) that are specific to the dynamic stack realignment using drap register that only the i386 backend does right now, and by using REG_FRAME_RELATED_EXPR or REG_CFA* notes we can't emulate those rules. The following patch instead does the deferring of the hard frame pointer save rule in dwarf2cfi.c Rule 18 handling and emits it on the (set hfp sp) assignment that must appear shortly after it and adds assertion that it is the case. The difference before/after the patch on the assembly is: --- pr99334.s~ 2021-03-26 15:42:40.881749380 +0100 +++ pr99334.s 2021-03-26 17:38:05.729161910 +0100 @@ -11,8 +11,8 @@ _func_with_dwarf_issue_: andq$-16, %rsp pushq -8(%r10) pushq %rbp - .cfi_escape 0x10,0x6,0x2,0x76,0 movq%rsp, %rbp + .cfi_escape 0x10,0x6,0x2,0x76,0 pushq %r15 pushq %r14 pushq %r13 i.e. does just what we IMHO need, after pushq %rbp %rbp still contains parent's frame value and so the save rule doesn't need to be overridden there, ditto at the start of the next insn before the side-effect took effect, and we override it only after it when %rbp already has the right value. If some other target adds dynamic stack realignment in the future and the offset 0 case wouldn't be true there, the code can be adjusted so that it works on all the drap architectures, I'm pretty sure the code would need other adjustments too. For the rule 18 and for the (set hfp sp) after it we already have asserts for
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #12 from CVS Commits --- The releases/gcc-9 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:c1780b4c6f1c0e91f10d13e70eb17f5d77f22bb0 commit r9-9438-gc1780b4c6f1c0e91f10d13e70eb17f5d77f22bb0 Author: Jakub Jelinek Date: Sat Mar 27 00:20:42 2021 +0100 dwarf2cfi: Defer queued register saves some more [PR99334] On the testcase in the PR with -fno-tree-sink -O3 -fPIC -fomit-frame-pointer -fno-strict-aliasing -mstackrealign we have prologue: <_func_with_dwarf_issue_>: 0: 4c 8d 54 24 08 lea0x8(%rsp),%r10 5: 48 83 e4 f0 and$0xfff0,%rsp 9: 41 ff 72 f8 pushq -0x8(%r10) d: 55 push %rbp e: 48 89 e5mov%rsp,%rbp 11: 41 57 push %r15 13: 41 56 push %r14 15: 41 55 push %r13 17: 41 54 push %r12 19: 41 52 push %r10 1b: 53 push %rbx 1c: 48 83 ec 20 sub$0x20,%rsp and emit 0014 CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8 DW_CFA_nop DW_CFA_nop 0018 0044 001c FDE cie= pc=..01d5 DW_CFA_advance_loc: 5 to 0005 DW_CFA_def_cfa: r10 (r10) ofs 0 DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 13 to 001b DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8) DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16) DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24) DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32) ... unwind info for that. The problem is when async signal (or stepping through in the debugger) stops after the pushq %rbp instruction and before movq %rsp, %rbp, the unwind info says that caller's %rbp is saved there at *%rbp, but that is not true, caller's %rbp is either still available in the %rbp register, or in *%rsp, only after executing the next instruction - movq %rsp, %rbp - the location for %rbp is correct. So, either we'd need to temporarily say: DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg7 (rsp): 0) DW_CFA_advance_loc: 3 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b or to me it seems more compact to just say: DW_CFA_advance_loc: 12 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b I've tried instead to deal with it through REG_FRAME_RELATED_EXPR from the backend, but that failed miserably as explained in the PR, dwarf2cfi.c has some rules (Rule 16 to Rule 19) that are specific to the dynamic stack realignment using drap register that only the i386 backend does right now, and by using REG_FRAME_RELATED_EXPR or REG_CFA* notes we can't emulate those rules. The following patch instead does the deferring of the hard frame pointer save rule in dwarf2cfi.c Rule 18 handling and emits it on the (set hfp sp) assignment that must appear shortly after it and adds assertion that it is the case. The difference before/after the patch on the assembly is: --- pr99334.s~ 2021-03-26 15:42:40.881749380 +0100 +++ pr99334.s 2021-03-26 17:38:05.729161910 +0100 @@ -11,8 +11,8 @@ _func_with_dwarf_issue_: andq$-16, %rsp pushq -8(%r10) pushq %rbp - .cfi_escape 0x10,0x6,0x2,0x76,0 movq%rsp, %rbp + .cfi_escape 0x10,0x6,0x2,0x76,0 pushq %r15 pushq %r14 pushq %r13 i.e. does just what we IMHO need, after pushq %rbp %rbp still contains parent's frame value and so the save rule doesn't need to be overridden there, ditto at the start of the next insn before the side-effect took effect, and we override it only after it when %rbp already has the right value. If some other target adds dynamic stack realignment in the future and the offset 0 case wouldn't be true there, the code can be adjusted so that it works on all the drap architectures, I'm pretty sure the code would need other adjustments too. For the rule 18 and for the (set hfp sp) after it we already have asserts for the
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #11 from CVS Commits --- The releases/gcc-10 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:f5df18504c1790413f293bfb50d40faa7f1ea860 commit r10-9624-gf5df18504c1790413f293bfb50d40faa7f1ea860 Author: Jakub Jelinek Date: Sat Mar 27 00:20:42 2021 +0100 dwarf2cfi: Defer queued register saves some more [PR99334] On the testcase in the PR with -fno-tree-sink -O3 -fPIC -fomit-frame-pointer -fno-strict-aliasing -mstackrealign we have prologue: <_func_with_dwarf_issue_>: 0: 4c 8d 54 24 08 lea0x8(%rsp),%r10 5: 48 83 e4 f0 and$0xfff0,%rsp 9: 41 ff 72 f8 pushq -0x8(%r10) d: 55 push %rbp e: 48 89 e5mov%rsp,%rbp 11: 41 57 push %r15 13: 41 56 push %r14 15: 41 55 push %r13 17: 41 54 push %r12 19: 41 52 push %r10 1b: 53 push %rbx 1c: 48 83 ec 20 sub$0x20,%rsp and emit 0014 CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8 DW_CFA_nop DW_CFA_nop 0018 0044 001c FDE cie= pc=..01d5 DW_CFA_advance_loc: 5 to 0005 DW_CFA_def_cfa: r10 (r10) ofs 0 DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 13 to 001b DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8) DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16) DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24) DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32) ... unwind info for that. The problem is when async signal (or stepping through in the debugger) stops after the pushq %rbp instruction and before movq %rsp, %rbp, the unwind info says that caller's %rbp is saved there at *%rbp, but that is not true, caller's %rbp is either still available in the %rbp register, or in *%rsp, only after executing the next instruction - movq %rsp, %rbp - the location for %rbp is correct. So, either we'd need to temporarily say: DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg7 (rsp): 0) DW_CFA_advance_loc: 3 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b or to me it seems more compact to just say: DW_CFA_advance_loc: 12 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b I've tried instead to deal with it through REG_FRAME_RELATED_EXPR from the backend, but that failed miserably as explained in the PR, dwarf2cfi.c has some rules (Rule 16 to Rule 19) that are specific to the dynamic stack realignment using drap register that only the i386 backend does right now, and by using REG_FRAME_RELATED_EXPR or REG_CFA* notes we can't emulate those rules. The following patch instead does the deferring of the hard frame pointer save rule in dwarf2cfi.c Rule 18 handling and emits it on the (set hfp sp) assignment that must appear shortly after it and adds assertion that it is the case. The difference before/after the patch on the assembly is: --- pr99334.s~ 2021-03-26 15:42:40.881749380 +0100 +++ pr99334.s 2021-03-26 17:38:05.729161910 +0100 @@ -11,8 +11,8 @@ _func_with_dwarf_issue_: andq$-16, %rsp pushq -8(%r10) pushq %rbp - .cfi_escape 0x10,0x6,0x2,0x76,0 movq%rsp, %rbp + .cfi_escape 0x10,0x6,0x2,0x76,0 pushq %r15 pushq %r14 pushq %r13 i.e. does just what we IMHO need, after pushq %rbp %rbp still contains parent's frame value and so the save rule doesn't need to be overridden there, ditto at the start of the next insn before the side-effect took effect, and we override it only after it when %rbp already has the right value. If some other target adds dynamic stack realignment in the future and the offset 0 case wouldn't be true there, the code can be adjusted so that it works on all the drap architectures, I'm pretty sure the code would need other adjustments too. For the rule 18 and for the (set hfp sp) after it we already have asserts for
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #10 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:1cdfc98a9981768c475fabf069ba4d3e460deb2a commit r11-7870-g1cdfc98a9981768c475fabf069ba4d3e460deb2a Author: Jakub Jelinek Date: Sat Mar 27 00:20:42 2021 +0100 dwarf2cfi: Defer queued register saves some more [PR99334] On the testcase in the PR with -fno-tree-sink -O3 -fPIC -fomit-frame-pointer -fno-strict-aliasing -mstackrealign we have prologue: <_func_with_dwarf_issue_>: 0: 4c 8d 54 24 08 lea0x8(%rsp),%r10 5: 48 83 e4 f0 and$0xfff0,%rsp 9: 41 ff 72 f8 pushq -0x8(%r10) d: 55 push %rbp e: 48 89 e5mov%rsp,%rbp 11: 41 57 push %r15 13: 41 56 push %r14 15: 41 55 push %r13 17: 41 54 push %r12 19: 41 52 push %r10 1b: 53 push %rbx 1c: 48 83 ec 20 sub$0x20,%rsp and emit 0014 CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8 DW_CFA_nop DW_CFA_nop 0018 0044 001c FDE cie= pc=..01d5 DW_CFA_advance_loc: 5 to 0005 DW_CFA_def_cfa: r10 (r10) ofs 0 DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 13 to 001b DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8) DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16) DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24) DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32) ... unwind info for that. The problem is when async signal (or stepping through in the debugger) stops after the pushq %rbp instruction and before movq %rsp, %rbp, the unwind info says that caller's %rbp is saved there at *%rbp, but that is not true, caller's %rbp is either still available in the %rbp register, or in *%rsp, only after executing the next instruction - movq %rsp, %rbp - the location for %rbp is correct. So, either we'd need to temporarily say: DW_CFA_advance_loc: 9 to 000e DW_CFA_expression: r6 (rbp) (DW_OP_breg7 (rsp): 0) DW_CFA_advance_loc: 3 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b or to me it seems more compact to just say: DW_CFA_advance_loc: 12 to 0011 DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 10 to 001b I've tried instead to deal with it through REG_FRAME_RELATED_EXPR from the backend, but that failed miserably as explained in the PR, dwarf2cfi.c has some rules (Rule 16 to Rule 19) that are specific to the dynamic stack realignment using drap register that only the i386 backend does right now, and by using REG_FRAME_RELATED_EXPR or REG_CFA* notes we can't emulate those rules. The following patch instead does the deferring of the hard frame pointer save rule in dwarf2cfi.c Rule 18 handling and emits it on the (set hfp sp) assignment that must appear shortly after it and adds assertion that it is the case. The difference before/after the patch on the assembly is: --- pr99334.s~ 2021-03-26 15:42:40.881749380 +0100 +++ pr99334.s 2021-03-26 17:38:05.729161910 +0100 @@ -11,8 +11,8 @@ _func_with_dwarf_issue_: andq$-16, %rsp pushq -8(%r10) pushq %rbp - .cfi_escape 0x10,0x6,0x2,0x76,0 movq%rsp, %rbp + .cfi_escape 0x10,0x6,0x2,0x76,0 pushq %r15 pushq %r14 pushq %r13 i.e. does just what we IMHO need, after pushq %rbp %rbp still contains parent's frame value and so the save rule doesn't need to be overridden there, ditto at the start of the next insn before the side-effect took effect, and we override it only after it when %rbp already has the right value. If some other target adds dynamic stack realignment in the future and the offset 0 case wouldn't be true there, the code can be adjusted so that it works on all the drap architectures, I'm pretty sure the code would need other adjustments too. For the rule 18 and for the (set hfp sp) after it we already have asserts for the drap
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #9 from Jakub Jelinek --- As I said on the mailing list, the above patch has problems, it relies on the insn that clobbers_queued_reg_save to be a single hardware instruction so that a debug info consumer or unwinding can't stop "in the middle of the instruction". We have various NONJUMP_INSN_P insns that violate that, for one inline asm, but also various patterns that emit more than one insn. E.g. on x86 they are usually (but unsure if we can guarantee that) marked by get_attr_type (insn) == TYPE_MULTI. I have tried to instead deal with this on the i386.c side with: --- i386.c.jj3 2021-03-25 21:05:35.554309579 +0100 +++ i386.c 2021-03-26 15:56:21.349642695 +0100 @@ -8355,9 +8355,33 @@ ix86_expand_prologue (void) if (m->fs.sp_offset == frame.hard_frame_pointer_offset) { + if (stack_realign_drap) + { + /* Pretend the push %[re]bp instruction is just +add $-wordsize, [%re]sp for CFI purposes. */ + rtx spadj = plus_constant (Pmode, stack_pointer_rtx, +-UNITS_PER_WORD); + rtx r = gen_rtx_SET (stack_pointer_rtx, spadj); + add_reg_note (insn, REG_FRAME_RELATED_EXPR, r); + } + insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; + if (stack_realign_drap) + { + /* And that the mov %[re]sp, %[re]bp instruction acts as +both mov %[re]bp, (%[re]sp) and mov %[re]sp, %[re]bp +together for CFI purposes. */ + rtx r = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); + XVECEXP (r, 0, 0) + = gen_rtx_SET (gen_rtx_MEM (word_mode, stack_pointer_rtx), + hard_frame_pointer_rtx); + XVECEXP (r, 0, 1) + = gen_rtx_SET (hard_frame_pointer_rtx, stack_pointer_rtx); + add_reg_note (insn, REG_FRAME_RELATED_EXPR, r); + } + if (m->fs.cfa_reg == stack_pointer_rtx) m->fs.cfa_reg = hard_frame_pointer_rtx; m->fs.fp_offset = m->fs.sp_offset; but unfortunately that doesn't work properly, because dwarf2cfi.c has special rule for that push %[re]bp with drap active, described as Rule 18. So I think we should instead change the dwarf2cfi.c rule 18 handling so that it waits with the reg save until the hfp = sp instruction after it. Generally, there is also the option of e.g. adding some insn attribute on targets that want it which would say which instructions are single undivisible hw instructions and use that get_attr_{single,undivisible} or how it would be called in dwarf2cfi.c to decide whether to emit queued reg saves before it or after it.
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #8 from Jakub Jelinek --- I wonder about: --- gcc/dwarf2cfi.c.jj 2021-03-02 11:25:47.217727061 +0100 +++ gcc/dwarf2cfi.c 2021-03-23 17:34:58.240281522 +0100 @@ -2705,12 +2705,15 @@ scan_trace (dw_trace_info *trace, bool e dwarf2out_flush_queued_reg_saves (); } else if (!NONJUMP_INSN_P (insn) - || clobbers_queued_reg_save (insn) || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL)) dwarf2out_flush_queued_reg_saves (); any_cfis_emitted = false; add_cfi_insn = insn; + + if (queued_reg_saves.length () && clobbers_queued_reg_save (insn)) + dwarf2out_flush_queued_reg_saves (); + scan_insn_after (insn); control = insn; } For calls or REG_CFA_FLUSH_QUEUE I can understand wanting to flush queued register saves after the previous instruction, but for clobbers_queued_reg_save cases I don't understand that. This is about the: pushq %rbp movq %rsp, %rbp case. On pushq %rbp we queue the DW_CFA_expression for %rbp (but use %rbp in the expression), then see clobbers_queued_reg_save (insn) on the movq %rsp, %rbp returning true because that instruction overwrites it. But as it isn't really a call, I believe at least the libgcc unwinder for async signals evaluates all FDE instructions until the current pc inclusive. pushq %rbp doesn't really change %rbp and CFA is computed from %r10 at that point, and when we are at the start of movq %rsp, %rbp, we still haven't changed %rbp. As it is not a call, it doesn't have a separate byte abused for in the middle of the instruction and so the only other possibility is after that instruction.
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #7 from Jakub Jelinek --- #c6 reproduces even on current trunk with -fno-tree-sink -O3 -fPIC -fomit-frame-pointer -fno-strict-aliasing -mstackrealign
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #6 from AJ D --- Test Case: -- typedef long int intptr_t; typedef unsigned long int uintptr_t; typedef intptr_t DummyType14; typedef intptr_t DummyType8; typedef struct DummyType15IntT DummyType15T; typedef struct DummyType15IntT *DummyType15; typedef struct DummyType13Struct DummyType13; typedef struct DummyType10Struct DummyType10; typedef struct DummyType4_struct DummyType4_struct; typedef struct DummyType4_struct *DummyType4; typedef struct DummyType4_struct DummyType6; typedef struct DummyType1Struct DummyType1; typedef struct DummyType2Struct DummyType2; typedef struct DummyType12Struct DummyType12; typedef double DummyType19; extern int DummyType20; extern int DummyType21; extern int DummyType22; struct DummyType13Struct { DummyType13 *dm1; void *dm2; }; typedef struct DummyType9Struct { DummyType13 *dm1; DummyType13 *dm2; int dm3; } DummyType9; struct DummyType10Struct { }; struct DummyType4_struct { void *dm1; int dm2; int dm3; int dm4; }; typedef struct DummyType5Struct { } DummyType5; typedef union DummyType18Union { DummyType12 *dm1; uintptr_t dm2; } DummyType18; struct DummyType1Struct { DummyType15 dm1; unsigned int dm2:1; }; typedef struct DummyType3Struct { DummyType18 dm1; } DummyType3; typedef struct DummyType11Struct { DummyType10 *dm1; double dm2; } DummyType11; typedef struct DummyType17Struct { DummyType2 *dm1; } DummyType17; typedef struct DummyType7Struct { DummyType6 *dm1; DummyType17 *dm2; } DummyType7; typedef struct DummyType16Struct { DummyType12 *dm1; } DummyType16; extern int func1(DummyType15, DummyType14, DummyType8*); extern int func2(DummyType2*); extern const DummyType12 *func3(DummyType2*); extern DummyType9 *func4(const DummyType12*); extern DummyType13* func5(void); extern DummyType9* func6(void); extern int func7(int); extern DummyType16 *func8(double, DummyType12*); DummyType5 *_func_with_dwarf_issue_(DummyType1 *arg1, DummyType2 *arg2, DummyType3 **arg3, unsigned int *arg4, unsigned int *arg5, DummyType4 *arg6, DummyType4 *arg7) { DummyType6 *var1 = 0; DummyType7 *var2 = 0; DummyType8 var3 = 0; *arg3 = 0; if (arg1->dm1 && func1((arg1->dm1), (DummyType14) (func2(arg2)), (DummyType8 *) ()) ) { var2 = (DummyType7 *)var3; if (var2) { DummyType9 *var4 = 0; DummyType9 *var5 = 0; DummyType5 *var6 = 0; DummyType10 *var7 = 0; DummyType11 *var8 = 0; int var9 = 0; DummyType12 *var10 = ((void *)0) ; var1 = var2->dm1; var4 = func4(func3(arg2)); { DummyType13 *var11; var11 = (var4)->dm1; while(var11){ var7 = (DummyType10 *) var11->dm2; var11 = var11->dm1; { for (; var9 < ((var1)->dm2); var9++) { var8 = (DummyType21 = (var9), (DummyType21 < 0 || DummyType21 >= (var1)->dm2) ? func7(0) : 0, sizeof(DummyType11 *) != (var1)->dm4 ? func7(1) : 0, ((DummyType11 * *)((var1)->dm1))[DummyType21]); if (var8->dm1) { if (var10 && var2->dm2->dm1 && arg1->dm2) { var10 = 0; } if (var2->dm2->dm1 && !var10) { if (!var5) { var5 = func6(); } { DummyType13 *var11; var11 = func5(); var11->dm2 = (void *)(var6); if(!((var5)->dm2)){ (var5)->dm1 = var11; (var5)->dm2 = var11; } else{ (var5)->dm2->dm1 = var11; (var5)->dm2 = var11; } (var5)->dm3++; var11->dm1 = (DummyType13 *)0; }; } else { func8(var8->dm2, var10); } } } } } }; } } return 0; } GCC Command Line: gcc -DSTATIC_LIBRARY -DINST64_ENABLE -Xassembler -mrelax-relocations=no -m64 -msse2 -fPIC -DSTATIC_LIBRARY -D__NO_STRING_INLINES -mstackrealign -DPEBLK_THREAD -DINST64_ENABLE -DLINUX -m64 -rdynamic -DMM_MODE=0 -DLINUX_X86_64 -fPIC -DLINUX_X86_64 -DLONG_PTR_64 -DVM_LITTLE_ENDIAN -DMM_MODE=0 -rdynamic -O3 -fPIC -fomit-frame-pointer -o test.o -O3 -msse2 -fno-strict-aliasing -fPIC -fomit-frame-pointer -c test.i GCC Version / Configuration --- vg-centos72-vm01> gcc --version gcc (GCC) 9.2.0 Copyright (C) 2019 Free Software Foundation,
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #5 from AJ D --- Created attachment 50437 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50437=edit Function _func_with_dwarf_issue_ should demonstrate the issue
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 AJ D changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|FIXED |--- Version|6.2.0 |9.2.0 --- Comment #4 from AJ D --- I can reproduce this issue with gcc 9.2, but this time, on a different routine (not on the previously reported routine). GCC Version gcc (GCC) 9.2.0 Copyright (C) 2019 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. GCC Configuration = Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/depot/qsc/QSCS/GCC/libexec/gcc/x86_64-centos-linux/9.2.0/lto-wrapper Target: x86_64-centos-linux Configured with: ../src/gcc-9.2.0/configure --prefix=/depot/gcc-9.2.0 --enable-bootstrap --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,fortran --disable-libgcj --with-cpu=generic --build=x86_64-centos-linux Thread model: posix gcc version 9.2.0 (GCC) Assembly Code = 2c10 : 2c10: 4c 8d 54 24 08 lea0x8(%rsp),%r10 2c15: 48 83 e4 f0 and$0xfff0,%rsp 2c19: 41 ff 72 f8 pushq -0x8(%r10) 2c1d: 55 push %rbp => 2c1e: 48 89 e5mov%rsp,%rbp 2c21: 41 57 push %r15 2c23: 41 56 push %r14 2c25: 41 55 push %r13 2c27: 41 54 push %r12 2c29: 41 52 push %r10 Interrupt happened while on this instruction. => 2c1e: 48 89 e5mov%rsp,%rbp Here (before executing this instruction), rbp is pointing to parent frame. So, the following DWARF doesn't look quite right. 06b0 0044 06b4 FDE cie= pc=2c10..3607 DW_CFA_advance_loc: 5 to 2c15 DW_CFA_def_cfa: r10 (r10) ofs 0 DW_CFA_advance_loc: 9 to 2c1e DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) DW_CFA_advance_loc: 13 to 2c2b DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref) DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8) DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16) DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24) DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32) >> DW_CFA_advance_loc: 9 to 2c1e >> DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0) Notice at address 2c1e, we are relying on rbp which is pointing to the caller procedure's rbp, not the current procedure's rbp. 06b0 0044 06b4 FDE cie= pc=2c10..3607 LOC CFA rbx rbp r12 r13 r14 r15 ra 2c10 rsp+8u u u u u u c-8 2c15 r10+0u u u u u u c-8 2c1e r10+0u exp u u u u c-8 2c2b exp u exp exp exp exp exp c-8 2c2c exp exp exp exp exp exp exp c-8 2e16 r10+0exp exp exp exp exp exp c-8 2e23 rsp+8exp exp exp exp exp exp c-8 2e24 exp exp exp exp exp exp exp c-8 Actual GDB disassemble at the crash point: Dump of assembler code for function raceGetDistSelectInterval: 0x2fd63bd0 <+0>: lea0x8(%rsp),%r10 0x2fd63bd5 <+5>: and$0xfff0,%rsp 0x2fd63bd9 <+9>: pushq -0x8(%r10) 0x2fd63bdd <+13>:push %rbp => 0x2fd63bde <+14>:mov%rsp,%rbp 0x2fd63be1 <+17>:push %r15 0x2fd63be3 <+19>:push %r14 I will add the .i file in few days (have to take care of IP issues as per my company guidelines).
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 Andrew Pinski changed: What|Removed |Added Resolution|--- |FIXED Target Milestone|--- |8.2 Status|WAITING |RESOLVED --- Comment #3 from Andrew Pinski --- so clsoing as fixed as GCC 7.x (and before) are no longer supported.
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 --- Comment #2 from AJ D --- The problem seems to have been addressed in gcc-8.x, at least in this particular function. I could reproduce this issue in gcc-7.4, but not with gcc-8.2, as can be seen below. Will have to check if this issue is showing up in any other functions. odcphy-vg-1294> module load gcc/7.4.0 odcphy-vg-1294> ./reproduce.csh 02f0 0044 02f4 FDE cie= pc=6570..680a LOC CFA rbx rbp r12 r13 r14 r15 ra 6570 rsp+8u u u u u u c-8 6575 r10+0u u u u u u c-8 657e r10+0u exp u u u u c-8 6589 r10+0u exp exp exp exp exp c-8 658e exp u exp exp exp exp exp c-8 6592 exp exp exp exp exp exp exp c-8 65f5 r10+0exp exp exp exp exp exp c-8 6602 rsp+8exp exp exp exp exp exp c-8 6608 exp exp exp exp exp exp exp c-8 odcphy-vg-1294> odcphy-vg-1294> module load gcc/8.2.0 odcphy-vg-1294> ./reproduce.csh 02c8 0034 02cc FDE cie= pc=6450..676f LOC CFA rbx rbp r12 r13 r14 r15 ra 6450 rsp+8u u u u u u c-8 6451 rsp+16 u c-16 u u u u c-8 6454 rbp+16 u c-16 u u u u c-8 645a rbp+16 u c-16 u c-40 c-32 c-24 c-8 645f rbp+16 u c-16 c-48 c-40 c-32 c-24 c-8 6463 rbp+16 c-56 c-16 c-48 c-40 c-32 c-24 c-8 6518 rsp+8c-56 c-16 c-48 c-40 c-32 c-24 c-8 6520 rbp+16 c-56 c-16 c-48 c-40 c-32 c-24 c-8 6550 rsp+8c-56 c-16 c-48 c-40 c-32 c-24 c-8 odcphy-vg-1294>
[Bug debug/99334] Generated DWARF unwind table issue while on instructions where rbp is pointing to callers stack frame
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99334 Richard Biener changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2021-03-02 Status|UNCONFIRMED |WAITING Target||x86_64-linux