[libcxx-commits] [PATCH] D114818: [libunwind] Fix unwind_leaffunction test

Leonard Chan via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 1 10:49:21 PST 2021


leonardchan added a comment.

In D114818#3163688 <https://reviews.llvm.org/D114818#3163688>, @mstorsjo wrote:

> In D114818#3162717 <https://reviews.llvm.org/D114818#3162717>, @leonardchan wrote:
>
>> Then the test passes, but it looks like unwinder skips past `func` (it jumps from `_Z18crashing_leaf_funcv` to `main`). Perhaps all this hints at an underlying issue in libunwind?
>
> Is this a case where a function ends with a call instruction, and the return address points at the address after the call instruction, which would be the first instruction of the next function?
>
> Can you provide disassembly of the linked binary (of the relevant functions) plus corresponding unwind info dumps (from e.g. llvm-dwarfdump)?



  00000000002134fc <_Z18crashing_leaf_funcv>:
  ; _Z18crashing_leaf_funcv():
    2134fc: 20 00 20 d4   brk     #0x1
    213500: c0 03 5f d6   ret
  
  0000000000213504 <_Z4funcv>:
  ; _Z4funcv():
    213504: fd 7b bf a9   stp     x29, x30, [sp, #-16]!
    213508: fd 03 00 91   mov     x29, sp
    21350c: fc ff ff 97   bl      0x2134fc <_Z18crashing_leaf_funcv>
    213510: fd 7b c1 a8   ldp     x29, x30, [sp], #16
    213514: c0 03 5f d6   ret
  
  0000000000213518 <main>:
  ; main():
    213518: ff c3 00 d1   sub     sp, sp, #48
    21351c: fd 7b 02 a9   stp     x29, x30, [sp, #32]
    213520: fd 83 00 91   add     x29, sp, #32
    213524: bf c3 1f b8   stur    wzr, [x29, #-4]
    213528: a0 83 1f b8   stur    w0, [x29, #-8]
    21352c: e1 0b 00 f9   str     x1, [sp, #16]
    213530: a0 00 80 52   mov     w0, #5
    213534: 01 00 00 90   adrp    x1, 0x213000 <main+0x1c>
    213538: 21 c0 12 91   add     x1, x1, #1200
    21353c: e1 07 00 f9   str     x1, [sp, #8]
    213540: f8 0f 00 94   bl      0x217520 <signal at plt>
    213544: e1 07 40 f9   ldr     x1, [sp, #8]
    213548: 80 00 80 52   mov     w0, #4
    21354c: f5 0f 00 94   bl      0x217520 <signal at plt>
    213550: ed ff ff 97   bl      0x213504 <_Z4funcv>
    213554: 20 00 80 12   mov     w0, #-2
    213558: fd 7b 42 a9   ldp     x29, x30, [sp, #32]
    21355c: ff c3 00 91   add     sp, sp, #48
    213560: c0 03 5f d6   ret

CIE (same for each of the following FDEs):

  00000088 00000014 00000000 CIE
    Format:                DWARF32
    Version:               1
    Augmentation:          "zR"
    Code alignment factor: 1
    Data alignment factor: -4
    Return address column: 30
    Augmentation data:     1B
  
    DW_CFA_def_cfa: WSP +0
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
  
    CFA=WSP

`main` FDE:

  00000118 0000001c 00000094 FDE cie=00000088 pc=00213518...00213564
    Format:       DWARF32
    DW_CFA_advance_loc: 12
    DW_CFA_def_cfa: W29 +16
    DW_CFA_offset: W30 -8
    DW_CFA_offset: W29 -16
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
  
    0x213518: CFA=WSP
    0x213524: CFA=W29+16: W29=[CFA-16], W30=[CFA-8]

`func` FDE:

  000000f8 0000001c 00000074 FDE cie=00000088 pc=00213504...00213518
    Format:       DWARF32
    DW_CFA_advance_loc: 8
    DW_CFA_def_cfa: W29 +16
    DW_CFA_offset: W30 -8
    DW_CFA_offset: W29 -16
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
  
    0x213504: CFA=WSP
    0x21350c: CFA=W29+16: W29=[CFA-16], W30=[CFA-8]

`crashing_leaf_func` FDE:

  000000e0 00000014 0000005c FDE cie=00000088 pc=002134fc...00213504
    Format:       DWARF32
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
  
    0x2134fc: CFA=WSP



> And/or, is this an issue where a tail call optimization makes the unwind stack entirely skip past a specific function in the stack?

The test is compiled without optimizations, so I don't think functions should be skipped in this case.

> What happens if you add e.g. a `__asm__ __volatile__("nop");` after the call to `__builtin_trap()`, and in `func()` where you call `crashing_leaf_func()`? That would add one extra instruction to the function (and should avoid any tail call optimizations) so that the return address (in the case of `func()`) or the program counter (in the case of the trap, if it points at the next instruction) points within the range of the current function, instead of pointing at the first instruction of the next function?

Added, but no changes in the functions that the unwinder sees. It still jumps from `_Z18crashing_leaf_funcv` to `main`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114818/new/

https://reviews.llvm.org/D114818



More information about the libcxx-commits mailing list