[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <C2470F2D-9E45-49D7-A03B-E6A7BB4B9738@jrtc27.com>
Date: Mon, 17 Jan 2022 17:33:40 +0000
From: Jessica Clarke <jrtc27@...c27.com>
To: Changbin Du <changbin.du@...il.com>
Cc: Paul Walmsley <paul.walmsley@...ive.com>,
Palmer Dabbelt <palmer@...belt.com>,
Albert Ou <aou@...s.berkeley.edu>,
linux-riscv <linux-riscv@...ts.infradead.org>,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] riscv: eliminate unreliable __builtin_frame_address(1)
On 17 Jan 2022, at 15:44, Changbin Du <changbin.du@...il.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
Powered by blists - more mailing lists