Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch: riscv: implement frame-pointer based stack unwinding #69912

Merged
merged 3 commits into from Apr 20, 2024

Conversation

ycsin
Copy link
Collaborator

@ycsin ycsin commented Mar 7, 2024

Influenced heavily by the RISCV64 stack unwinding implementation in the Linux kernel.

static void func2(int a)
{
printf("%d: %s\n", a, __func__);
if (a >= 5) {
k_oops();
}
func1(a + 1);
}
static void func1(int a)
{
printf("%d: %s\n", a, __func__);
func2(a + 1);
}
int main(void)
{
printf("Hello World! %s\n", CONFIG_BOARD);
func1(1);
return 0;
}

$ west build -b qemu_riscv64 -p auto -t run zephyr/tests/arch/common/stack_unwind/
...
-- west build: running target run
[1/103] Preparing syscall dependency handling

[3/103] Generating include/generated/version.h
-- Zephyr version: 3.6.99 (/Users/ycsin/zephyrproject/zephyr), build: v3.6.0-2575-g14149b1de14d
[102/103] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
             RAM:       52260 B       256 MB      0.02%
        IDT_LIST:          0 GB         2 KB      0.00%
Generating files from /Users/ycsin/zephyrproject/build/zephyr/zephyr.elf for board: qemu_riscv64
[102/103] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: riscv64
*** Booting Zephyr OS build v3.6.0-2575-g14149b1de14d ***
Hello World! qemu_riscv64
1: func1
2: func2
3: func1
4: func2
5: func1
6: func2
E:      a0: 0000000000000003    t0: 0000000000000000
E:      a1: 0000000080008d1f    t1: 000000000000004c
E:      a2: 000000000000000a    t2: 0000000000000053
E:      a3: 000000008000a210    t3: 000000000000002a
E:      a4: 000000008000a210    t4: 000000000000002e
E:      a5: 0000000000000004    t5: 000000000000007f
E:      a6: 0000000000000068    t6: 0000000000000010
E:      a7: 000000000000006a
E:      ra: 00000000800003f8
E:    mepc: 0000000080000406
E: mstatus: 0000000a00021880
E: 
E: call trace:
E:       0: fp: 000000008000cac0   ra: 0000000080000442
E:       1: fp: 000000008000cae0   ra: 000000008000040e
E:       2: fp: 000000008000cb00   ra: 0000000080000442
E:       3: fp: 000000008000cb20   ra: 000000008000040e
E:       4: fp: 000000008000cb40   ra: 0000000080000442
E:       5: fp: 000000008000cb60   ra: 000000008000046e
E:       6: fp: 000000008000cb70   ra: 0000000080002382
E:       7: fp: 000000008000cb80   ra: 00000000800007fe
E: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
E: Current thread: 0x8000a210 (main)
E: Halting system
qemu-system-riscv64: terminating on signal 2 from pid 2110 (<unknown process>)
ninja: build stopped: interrupted by user.
$ ../zephyr-sdk-0.16.5-1/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-addr2line -a 0000000080000442 -e build/zephyr/zephyr.elf
0x0000000080000442
/Users/ycsin/zephyrproject/zephyr/tests/arch/common/stack_unwind/src/main.c:30
$ ../zephyr-sdk-0.16.5-1/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-addr2line -a 000000008000040e -e build/zephyr/zephyr.elf
0x000000008000040e
/Users/ycsin/zephyrproject/zephyr/tests/arch/common/stack_unwind/src/main.c:24
$ ../zephyr-sdk-0.16.5-1/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-addr2line -a 000000008000046e -e build/zephyr/zephyr.elf
0x000000008000046e
/Users/ycsin/zephyrproject/zephyr/tests/arch/common/stack_unwind/src/main.c:39
$ ../zephyr-sdk-0.16.5-1/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-addr2line -a 0000000080002382 -e build/zephyr/zephyr.elf
0x0000000080002382
/Users/ycsin/zephyrproject/zephyr/kernel/include/kthread.h:176
$ ../zephyr-sdk-0.16.5-1/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-addr2line -a 00000000800007fe -e build/zephyr/zephyr.elf
0x00000000800007fe
/Users/ycsin/zephyrproject/zephyr/include/zephyr/kernel.h:593

@ycsin ycsin force-pushed the pr/riscv_stack_unwind branch 2 times, most recently from dd23d5b to a7942b1 Compare March 7, 2024 11:15
@ycsin ycsin requested a review from cfriedt March 7, 2024 11:20
@ycsin ycsin marked this pull request as ready for review March 7, 2024 12:40
@zephyrbot zephyrbot added the area: RISCV RISCV Architecture (32-bit & 64-bit) label Mar 7, 2024
@cfriedt
Copy link
Member

cfriedt commented Mar 8, 2024

@ycsin - LGTM - I wonder if it's possible to add a check to a new or existing testsuite.

@ycsin ycsin requested a review from con-pax March 8, 2024 12:00
@ycsin
Copy link
Collaborator Author

ycsin commented Mar 8, 2024

@ycsin - LGTM - I wonder if it's possible to add a check to a new or existing testsuite.

Maybe in https://github.com/zephyrproject-rtos/zephyr/tree/main/tests/kernel/fatal/exception ? I'll try.

@con-pax
Copy link
Contributor

con-pax commented Mar 8, 2024

Hey @ycsin,

This looks really cool. I am away now, but I can give this a try out next week?

@ycsin ycsin force-pushed the pr/riscv_stack_unwind branch 2 times, most recently from aa0e5f9 to 7a5c717 Compare March 14, 2024 05:04
uLipe
uLipe previously approved these changes Mar 23, 2024
@ycsin
Copy link
Collaborator Author

ycsin commented Apr 11, 2024

Rebased and the changes to esp32c3 is now being worked out in #71363 instead, CI is expected to fail in this PR on esp32c3 builds until #71388 is merged

@ycsin ycsin marked this pull request as draft April 11, 2024 03:48
Influenced heavily by the RISCV64 stack unwinding
implementation in the Linux kernel.

`CONFIG_RISCV_EXCEPTION_STACK_TRACE` can be enabled by
configuring the following Kconfigs:

```prj.conf
CONFIG_DEBUG_INFO=y
CONFIG_EXCEPTION_STACK_TRACE=y
CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT=y
CONFIG_OMIT_FRAME_POINTER=n
```

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Added test for archs that support it. It triggers an exception
and verify that the fatal message has stack unwind info.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
@ycsin ycsin marked this pull request as ready for review April 17, 2024 08:54
@ycsin
Copy link
Collaborator Author

ycsin commented Apr 17, 2024

Rebased on top of #71388, CI is green now.

ping @con-pax @cfriedt @carlocaione @fkokosinski @uLipe

cfriedt
cfriedt previously approved these changes Apr 17, 2024
Add an entry in the RISC-V arch section about the
implementation of frame-pointer based stack unwinding.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
@zephyrbot zephyrbot added the Release Notes To be mentioned in the release notes label Apr 19, 2024
@ycsin ycsin requested a review from cfriedt April 19, 2024 05:13
@@ -38,6 +38,24 @@ config RISCV_ALWAYS_SWITCH_THROUGH_ECALL
and most people should say n here to minimize context switching
overhead.

config RISCV_ENABLE_FRAME_POINTER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to make this a generic arch kconfig (CONFIG_FRAME_POINTER), we now have two architectures doing this

and OMIT_FRAME_POINTER. It is automatically enabled when the frame
pointer unwinding is enabled.

config RISCV_EXCEPTION_STACK_TRACE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@nashif nashif merged commit 6a497ac into zephyrproject-rtos:main Apr 20, 2024
20 checks passed
@ycsin ycsin deleted the pr/riscv_stack_unwind branch April 21, 2024 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Architectures area: RISCV RISCV Architecture (32-bit & 64-bit) platform: ESP32 Espressif ESP32 Release Notes To be mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants