Messages in this thread | | | Subject | Re: [PATCH] riscv: eliminate unreliable __builtin_frame_address(1) | From | Jessica Clarke <> | Date | Mon, 17 Jan 2022 17:33:40 +0000 |
| |
On 17 Jan 2022, at 15:44, Changbin Du <changbin.du@gmail.com> wrote: > > I tried different pieces of code which uses __builtin_frame_address(1) > (with both gcc version 7.5.0 and 10.3.0) to verify whether it works as > expected on riscv64. The result is negative. > > What the compiler had generated is as below: > 31 fp = (unsigned long)__builtin_frame_address(1); > 0xffffffff80006024 <+200>: ld s1,0(s0) > > It takes '0(s0)' as the address of frame 1 (caller), but the actual address > should be '-16(s0)'. > > | ... | <-+ > +-----------------+ | > | return address | | > | previous fp | | > | saved registers | | > | local variables | | > $fp --> | ... | | > +-----------------+ | > | return address | | > | previous fp --------+ > | saved registers | > $sp --> | local variables | > +-----------------+ > > This leads the kernel can not dump the full stack trace on riscv. > > [ 7.222126][ T1] Call Trace: > [ 7.222804][ T1] [<ffffffff80006058>] dump_backtrace+0x2c/0x3a > > This problem is not exposed on most riscv builds just because the '0(s0)' > occasionally is the address frame 2 (caller's caller), if only ra and fp > are stored in frame 1 (caller). > > | ... | <-+ > +-----------------+ | > | return address | | > $fp --> | previous fp | | > +-----------------+ | > | return address | | > | previous fp --------+ > | saved registers | > $sp --> | local variables | > +-----------------+ > > This could be a *bug* of gcc that should be fixed. But as noted in gcc > manual "Calling this function with a nonzero argument can have > unpredictable effects, including crashing the calling program.", let's > remove the '__builtin_frame_address(1)' in backtrace code.
Yes, this is a bug, that is always wrong. LLVM gets this right.
https://godbolt.org/z/MrhsoPPM6
Jess
| |